Subversion Repositories Kolibri OS

Rev

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

Rev 5363 Rev 5522
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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.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
        rx_desc         rb RX_RING_SIZE*sizeof.RDESC*2
280
        rx_desc         rb RX_RING_SIZE*sizeof.RDESC*2
281
 
281
 
282
        rb 0x100 - ($ and 0xff) ; align 256
282
        rb 0x100 - ($ and 0xff) ; align 256
283
        tx_desc         rb TX_RING_SIZE*sizeof.TDESC*2
283
        tx_desc         rb TX_RING_SIZE*sizeof.TDESC*2
284
 
284
 
285
ends
285
ends
286
 
286
 
287
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
287
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
288
;;                        ;;
288
;;                        ;;
289
;; proc START             ;;
289
;; proc START             ;;
290
;;                        ;;
290
;;                        ;;
291
;; (standard driver proc) ;;
291
;; (standard driver proc) ;;
292
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
292
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
293
 
293
 
294
proc START c, reason:dword, cmdline:dword
294
proc START c, reason:dword, cmdline:dword
295
 
295
 
296
        cmp     [reason], DRV_ENTRY
296
        cmp     [reason], DRV_ENTRY
297
        jne     .fail
297
        jne     .fail
298
 
298
 
299
        DEBUGF  1,"Loading driver\n"
299
        DEBUGF  1,"Loading driver\n"
300
        invoke  RegService, my_service, service_proc
300
        invoke  RegService, my_service, service_proc
301
        ret
301
        ret
302
 
302
 
303
  .fail:
303
  .fail:
304
        xor     eax, eax
304
        xor     eax, eax
305
        ret
305
        ret
306
 
306
 
307
endp
307
endp
308
 
308
 
309
 
309
 
310
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
310
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
311
;;                        ;;
311
;;                        ;;
312
;; proc SERVICE_PROC      ;;
312
;; proc SERVICE_PROC      ;;
313
;;                        ;;
313
;;                        ;;
314
;; (standard driver proc) ;;
314
;; (standard driver proc) ;;
315
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
315
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
316
 
316
 
317
align 4
317
align 4
318
proc service_proc stdcall, ioctl:dword
318
proc service_proc stdcall, ioctl:dword
319
 
319
 
320
        mov     edx, [ioctl]
320
        mov     edx, [ioctl]
321
        mov     eax, [edx + IOCTL.io_code]
321
        mov     eax, [edx + IOCTL.io_code]
322
 
322
 
323
;------------------------------------------------------
323
;------------------------------------------------------
324
 
324
 
325
        cmp     eax, 0 ;SRV_GETVERSION
325
        cmp     eax, 0 ;SRV_GETVERSION
326
        jne     @F
326
        jne     @F
327
 
327
 
328
        cmp     [edx + IOCTL.out_size], 4
328
        cmp     [edx + IOCTL.out_size], 4
329
        jb      .fail
329
        jb      .fail
330
        mov     eax, [edx + IOCTL.output]
330
        mov     eax, [edx + IOCTL.output]
331
        mov     dword[eax], API_VERSION
331
        mov     dword[eax], API_VERSION
332
 
332
 
333
        xor     eax, eax
333
        xor     eax, eax
334
        ret
334
        ret
335
 
335
 
336
;------------------------------------------------------
336
;------------------------------------------------------
337
  @@:
337
  @@:
338
        cmp     eax, 1 ;SRV_HOOK
338
        cmp     eax, 1 ;SRV_HOOK
339
        jne     .fail
339
        jne     .fail
340
 
340
 
341
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
341
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
342
        jb      .fail
342
        jb      .fail
343
 
343
 
344
        mov     eax, [edx + IOCTL.input]
344
        mov     eax, [edx + IOCTL.input]
345
        cmp     byte[eax], 1                            ; 1 means device number and bus number (pci) are given
345
        cmp     byte[eax], 1                            ; 1 means device number and bus number (pci) are given
346
        jne     .fail                                   ; other types arent supported for this card yet
346
        jne     .fail                                   ; other types arent supported for this card yet
347
 
347
 
348
; check if the device is already listed
348
; check if the device is already listed
349
 
349
 
350
        mov     esi, device_list
350
        mov     esi, device_list
351
        mov     ecx, [devices]
351
        mov     ecx, [devices]
352
        test    ecx, ecx
352
        test    ecx, ecx
353
        jz      .firstdevice
353
        jz      .firstdevice
354
 
354
 
355
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
355
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
356
        mov     ax, [eax+1]                             ;
356
        mov     ax, [eax+1]                             ;
357
  .nextdevice:
357
  .nextdevice:
358
        mov     ebx, [esi]
358
        mov     ebx, [esi]
359
        cmp     al, byte[ebx + device.pci_bus]
359
        cmp     al, byte[ebx + device.pci_bus]
360
        jne     .next
360
        jne     .next
361
        cmp     ah, byte[ebx + device.pci_dev]
361
        cmp     ah, byte[ebx + device.pci_dev]
362
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
362
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
363
  .next:
363
  .next:
364
        add     esi, 4
364
        add     esi, 4
365
        loop    .nextdevice
365
        loop    .nextdevice
366
 
366
 
367
 
367
 
368
; This device doesnt have its own eth_device structure yet, lets create one
368
; This device doesnt have its own eth_device structure yet, lets create one
369
  .firstdevice:
369
  .firstdevice:
370
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
370
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
371
        jae     .fail
371
        jae     .fail
372
 
372
 
373
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
373
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
374
 
374
 
375
; Fill in the direct call addresses into the struct
375
; Fill in the direct call addresses into the struct
376
 
376
 
377
        mov     [ebx + device.reset], reset
377
        mov     [ebx + device.reset], reset
378
        mov     [ebx + device.transmit], transmit
378
        mov     [ebx + device.transmit], transmit
379
        mov     [ebx + device.unload], unload
379
        mov     [ebx + device.unload], unload
380
        mov     [ebx + device.name], my_service
380
        mov     [ebx + device.name], my_service
381
 
381
 
382
; save the pci bus and device numbers
382
; save the pci bus and device numbers
383
 
383
 
384
        mov     eax, [edx + IOCTL.input]
384
        mov     eax, [edx + IOCTL.input]
385
        movzx   ecx, byte[eax+1]
385
        movzx   ecx, byte[eax+1]
386
        mov     [ebx + device.pci_bus], ecx
386
        mov     [ebx + device.pci_bus], ecx
387
        movzx   ecx, byte[eax+2]
387
        movzx   ecx, byte[eax+2]
388
        mov     [ebx + device.pci_dev], ecx
388
        mov     [ebx + device.pci_dev], ecx
389
 
389
 
390
; Now, it's time to find the base mmio addres of the PCI device
390
; Now, it's time to find the base mmio addres of the PCI device
391
 
391
 
392
        stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev] ; returns in eax
392
        stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev] ; returns in eax
393
 
393
 
394
; Create virtual mapping of the physical memory
394
; Create virtual mapping of the physical memory
395
 
395
 
396
        invoke  MapIoMem, eax, 10000h, PG_SW+PG_NOCACHE
396
        invoke  MapIoMem, eax, 10000h, PG_SW+PG_NOCACHE
397
        mov     [ebx + device.mmio_addr], eax
397
        mov     [ebx + device.mmio_addr], eax
398
 
398
 
399
; We've found the mmio address, find IRQ now
399
; We've found the mmio address, find IRQ now
400
 
400
 
401
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
401
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
402
        mov     [ebx + device.irq_line], al
402
        mov     [ebx + device.irq_line], al
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
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.mmio_addr]:8
405
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + 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
        test    eax, eax
417
        test    eax, eax
418
        jnz     .destroy
418
        jnz     .destroy
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
        DEBUGF  2,"Loading driver failed\n"
446
        DEBUGF  2,"Loading driver failed\n"
447
        or      eax, -1
447
        or      eax, -1
448
        ret
448
        ret
449
 
449
 
450
;------------------------------------------------------
450
;------------------------------------------------------
451
endp
451
endp
452
 
452
 
453
 
453
 
454
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
454
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
455
;;                                                                        ;;
455
;;                                                                        ;;
456
;;        Actual Hardware dependent code starts here                      ;;
456
;;        Actual Hardware dependent code starts here                      ;;
457
;;                                                                        ;;
457
;;                                                                        ;;
458
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
458
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
459
 
459
 
460
 
460
 
461
align 4
461
align 4
462
unload:
462
unload:
463
 
463
 
464
        DEBUGF  1,"Unload\n"
464
        DEBUGF  1,"Unload\n"
465
 
465
 
466
        ; TODO: (in this particular order)
466
        ; TODO: (in this particular order)
467
        ;
467
        ;
468
        ; - Stop the device
468
        ; - Stop the device
469
        ; - Detach int handler
469
        ; - Detach int handler
470
        ; - Remove device from local list (device_list)
470
        ; - Remove device from local list (device_list)
471
        ; - call unregister function in kernel
471
        ; - call unregister function in kernel
472
        ; - Remove all allocated structures and buffers the card used
472
        ; - Remove all allocated structures and buffers the card used
473
 
473
 
474
        or      eax, -1
474
        or      eax, -1
475
 
-
 
476
        ret
475
        ret
477
 
476
 
478
 
477
 
479
 
478
 
480
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
479
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
481
;;
480
;;
482
;;  probe: enables the device (if it really is I8254X)
481
;;  probe: enables the device (if it really is I8254X)
483
;;
482
;;
484
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
483
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
485
align 4
484
align 4
486
probe:
485
probe:
487
 
486
 
488
        DEBUGF  1,"Probe\n"
487
        DEBUGF  1,"Probe\n"
489
 
488
 
490
; Make the device a bus master
489
; Make the device a bus master
491
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
490
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
492
        or      al, PCI_CMD_MASTER
491
        or      al, PCI_CMD_MASTER
493
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
492
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
494
 
493
 
495
        ; TODO: validate the device
494
        ; TODO: validate the device
496
 
495
 
497
        call    read_mac
496
        call    read_mac
498
 
497
 
499
        movzx   eax, [ebx + device.irq_line]
498
        movzx   eax, [ebx + device.irq_line]
500
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
499
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
501
        invoke  AttachIntHandler, eax, int_handler, ebx
500
        invoke  AttachIntHandler, eax, int_handler, ebx
502
        test    eax, eax
501
        test    eax, eax
503
        jnz     @f
502
        jnz     @f
504
        DEBUGF  2,"Could not attach int handler!\n"
503
        DEBUGF  2,"Could not attach int handler!\n"
505
        or      eax, -1
504
        or      eax, -1
506
        ret
505
        ret
507
  @@:
506
  @@:
508
 
507
 
509
 
508
 
510
reset_dontstart:
509
reset_dontstart:
511
        DEBUGF  1,"Reset\n"
510
        DEBUGF  1,"Reset\n"
512
 
511
 
513
        mov     esi, [ebx + device.mmio_addr]
512
        mov     esi, [ebx + device.mmio_addr]
514
 
513
 
515
        or      dword[esi + REG_CTRL], CTRL_RST         ; reset device
514
        or      dword[esi + REG_CTRL], CTRL_RST         ; reset device
516
  .loop:
515
  .loop:
517
        push    esi
516
        push    esi
518
        xor     esi, esi
517
        xor     esi, esi
519
        inc     esi
518
        inc     esi
520
        invoke  Sleep
519
        invoke  Sleep
521
        pop     esi
520
        pop     esi
522
        test    dword[esi + REG_CTRL], CTRL_RST
521
        test    dword[esi + REG_CTRL], CTRL_RST
523
        jnz     .loop
522
        jnz     .loop
524
 
523
 
525
        mov     dword[esi + REG_IMC], 0xffffffff        ; Disable all interrupt causes
524
        mov     dword[esi + REG_IMC], 0xffffffff        ; Disable all interrupt causes
526
        mov     eax, dword [esi + REG_ICR]              ; Clear any pending interrupts
525
        mov     eax, dword [esi + REG_ICR]              ; Clear any pending interrupts
527
        mov     dword[esi + REG_ITR], 0                 ; Disable interrupt throttling logic
526
        mov     dword[esi + REG_ITR], 0                 ; Disable interrupt throttling logic
528
 
527
 
529
        mov     dword[esi + REG_PBA], 0x00000004        ; PBA: set the RX buffer size to 4KB (TX buffer is calculated as 64-RX buffer)
528
        mov     dword[esi + REG_PBA], 0x00000004        ; PBA: set the RX buffer size to 4KB (TX buffer is calculated as 64-RX buffer)
530
        mov     dword[esi + REG_RDTR], 0                ; RDTR: set no delay
529
        mov     dword[esi + REG_RDTR], 0                ; RDTR: set no delay
531
 
530
 
532
        mov     dword[esi + REG_TXCW], 0x80008060       ; TXCW: set ANE, TxConfigWord (Half/Full duplex, Next Page Reqest)
531
        mov     dword[esi + REG_TXCW], 0x80008060       ; TXCW: set ANE, TxConfigWord (Half/Full duplex, Next Page Reqest)
533
 
532
 
534
        mov     eax, [esi + REG_CTRL]
533
        mov     eax, [esi + REG_CTRL]
535
        or      eax, 1 shl 6 + 1 shl 5
534
        or      eax, 1 shl 6 + 1 shl 5
536
        and     eax, not (1 shl 3 + 1 shl 7 + 1 shl 30 + 1 shl 31)
535
        and     eax, not (1 shl 3 + 1 shl 7 + 1 shl 30 + 1 shl 31)
537
        mov     dword [esi + REG_CTRL], eax             ; CTRL: clear LRST, set SLU and ASDE, clear RSTPHY, VME, and ILOS
536
        mov     dword [esi + REG_CTRL], eax             ; CTRL: clear LRST, set SLU and ASDE, clear RSTPHY, VME, and ILOS
538
 
537
 
539
        lea     edi, [esi + 0x5200]                     ; MTA: reset
538
        lea     edi, [esi + 0x5200]                     ; MTA: reset
540
        mov     eax, 0xffffffff
539
        mov     eax, 0xffffffff
541
        stosd
540
        stosd
542
        stosd
541
        stosd
543
        stosd
542
        stosd
544
        stosd
543
        stosd
545
 
544
 
546
        call    init_rx
545
        call    init_rx
547
        test    eax, eax
546
        test    eax, eax
548
        jnz     .fail
547
        jnz     .fail
549
        call    init_tx
548
        call    init_tx
550
 
549
 
551
        xor     eax, eax
550
        xor     eax, eax
552
  .fail:
551
  .fail:
553
        ret
552
        ret
554
 
553
 
555
 
554
 
556
 
555
 
557
align 4
556
align 4
558
init_rx:
557
init_rx:
559
 
558
 
560
        lea     edi, [ebx + device.rx_desc]
559
        lea     edi, [ebx + device.rx_desc]
561
        mov     ecx, RX_RING_SIZE
560
        mov     ecx, RX_RING_SIZE
562
  .loop:
561
  .loop:
-
 
562
        push    ecx
563
        push    ecx edi
563
        push    edi
564
        invoke  KernelAlloc, MAX_PKT_SIZE
564
        invoke  NetAlloc, MAX_PKT_SIZE+NET_BUFF.data
565
        test    eax, eax
565
        test    eax, eax
566
        jz      .out_of_mem
566
        jz      .out_of_mem
567
        DEBUGF  1,"RX buffer: 0x%x\n", eax
567
        DEBUGF  1,"RX buffer: 0x%x\n", eax
568
        pop     edi
568
        pop     edi
569
        mov     dword[edi + RX_RING_SIZE*sizeof.RDESC], eax
569
        mov     dword[edi + RX_RING_SIZE*sizeof.RDESC], eax
570
        push    edi
570
        push    edi
571
        invoke  GetPhysAddr
571
        invoke  GetPhysAddr
572
        pop     edi
572
        pop     edi
-
 
573
        add     eax, NET_BUFF.data
573
        mov     [edi + RDESC.addr_l], eax
574
        mov     [edi + RDESC.addr_l], eax
574
        mov     [edi + RDESC.addr_h], 0
575
        mov     [edi + RDESC.addr_h], 0
575
        mov     [edi + RDESC.status_l], 0
576
        mov     [edi + RDESC.status_l], 0
576
        mov     [edi + RDESC.status_h], 0
577
        mov     [edi + RDESC.status_h], 0
577
        add     edi, sizeof.RDESC
578
        add     edi, sizeof.RDESC
578
        pop     ecx
579
        pop     ecx
579
        dec     ecx
580
        dec     ecx
580
        jnz     .loop
581
        jnz     .loop
581
 
582
 
582
        mov     [ebx + device.cur_rx], 0
583
        mov     [ebx + device.cur_rx], 0
583
 
584
 
584
        lea     eax, [ebx + device.rx_desc]
585
        lea     eax, [ebx + device.rx_desc]
585
        invoke  GetPhysAddr
586
        invoke  GetPhysAddr
586
        mov     dword[esi + REG_RDBAL], eax                             ; Receive Descriptor Base Address Low
587
        mov     dword[esi + REG_RDBAL], eax                             ; Receive Descriptor Base Address Low
587
        mov     dword[esi + REG_RDBAH], 0                               ; Receive Descriptor Base Address High
588
        mov     dword[esi + REG_RDBAH], 0                               ; Receive Descriptor Base Address High
588
        mov     dword[esi + REG_RDLEN], RX_RING_SIZE*sizeof.RDESC       ; Receive Descriptor Length
589
        mov     dword[esi + REG_RDLEN], RX_RING_SIZE*sizeof.RDESC       ; Receive Descriptor Length
589
        mov     dword[esi + REG_RDH], 0                                 ; Receive Descriptor Head
590
        mov     dword[esi + REG_RDH], 0                                 ; Receive Descriptor Head
590
        mov     dword[esi + REG_RDT], RX_RING_SIZE-1                    ; Receive Descriptor Tail
591
        mov     dword[esi + REG_RDT], RX_RING_SIZE-1                    ; Receive Descriptor Tail
591
        mov     dword[esi + REG_RCTL], RCTL_SBP or RCTL_BAM or RCTL_SECRC or RCTL_UPE or RCTL_MPE
592
        mov     dword[esi + REG_RCTL], RCTL_SBP or RCTL_BAM or RCTL_SECRC or RCTL_UPE or RCTL_MPE
592
        ; Store Bad Packets, Broadcast Accept Mode, Strip Ethernet CRC from incoming packet, Promiscuous mode
593
        ; Store Bad Packets, Broadcast Accept Mode, Strip Ethernet CRC from incoming packet, Promiscuous mode
593
        xor     eax, eax        ; success!
594
        xor     eax, eax        ; success!
594
        ret
595
        ret
595
 
596
 
596
  .out_of_mem:
597
  .out_of_mem:
597
        DEBUGF  2,"Out of memory!\n"
598
        DEBUGF  2,"Out of memory!\n"
598
        pop     edi ecx
599
        pop     edi ecx
599
        or      eax, -1         ; error!
600
        or      eax, -1         ; error!
600
        ret
601
        ret
601
 
602
 
602
 
603
 
603
 
604
 
604
align 4
605
align 4
605
init_tx:
606
init_tx:
606
 
607
 
607
        lea     edi, [ebx + device.tx_desc]
608
        lea     edi, [ebx + device.tx_desc]
608
        mov     ecx, TX_RING_SIZE
609
        mov     ecx, TX_RING_SIZE
609
  .loop:
610
  .loop:
610
        mov     [edi + TDESC.addr_l], eax
611
        mov     [edi + TDESC.addr_l], eax
611
        mov     [edi + TDESC.addr_h], 0
612
        mov     [edi + TDESC.addr_h], 0
612
        mov     [edi + TDESC.length_cso_cmd], 0
613
        mov     [edi + TDESC.length_cso_cmd], 0
613
        mov     [edi + TDESC.status], 0
614
        mov     [edi + TDESC.status], 0
614
        add     edi, sizeof.TDESC
615
        add     edi, sizeof.TDESC
615
        dec     ecx
616
        dec     ecx
616
        jnz     .loop
617
        jnz     .loop
617
 
618
 
618
        mov     [ebx + device.cur_tx], 0
619
        mov     [ebx + device.cur_tx], 0
619
        mov     [ebx + device.last_tx], 0
620
        mov     [ebx + device.last_tx], 0
620
 
621
 
621
        lea     eax, [ebx + device.tx_desc]
622
        lea     eax, [ebx + device.tx_desc]
622
        invoke  GetPhysAddr
623
        invoke  GetPhysAddr
623
        mov     dword[esi + REG_TDBAL], eax                             ; Transmit Descriptor Base Address Low
624
        mov     dword[esi + REG_TDBAL], eax                             ; Transmit Descriptor Base Address Low
624
        mov     dword[esi + REG_TDBAH], 0                               ; Transmit Descriptor Base Address High
625
        mov     dword[esi + REG_TDBAH], 0                               ; Transmit Descriptor Base Address High
625
        mov     dword[esi + REG_TDLEN], RX_RING_SIZE*sizeof.TDESC       ; Transmit Descriptor Length
626
        mov     dword[esi + REG_TDLEN], RX_RING_SIZE*sizeof.TDESC       ; Transmit Descriptor Length
626
        mov     dword[esi + REG_TDH], 0                                 ; Transmit Descriptor Head
627
        mov     dword[esi + REG_TDH], 0                                 ; Transmit Descriptor Head
627
        mov     dword[esi + REG_TDT], 0                                 ; Transmit Descriptor Tail
628
        mov     dword[esi + REG_TDT], 0                                 ; Transmit Descriptor Tail
628
        mov     dword[esi + REG_TCTL], 0x010400fa                       ; Enabled, Pad Short Packets, 15 retrys, 64-byte COLD, Re-transmit on Late Collision
629
        mov     dword[esi + REG_TCTL], 0x010400fa                       ; Enabled, Pad Short Packets, 15 retrys, 64-byte COLD, Re-transmit on Late Collision
629
        mov     dword[esi + REG_TIPG], 0x0060200A                       ; IPGT 10, IPGR1 8, IPGR2 6
630
        mov     dword[esi + REG_TIPG], 0x0060200A                       ; IPGT 10, IPGR1 8, IPGR2 6
630
 
631
 
631
        ret
632
        ret
632
 
633
 
633
 
634
 
634
align 4
635
align 4
635
reset:
636
reset:
636
        call    reset_dontstart
637
        call    reset_dontstart
637
        test    eax, eax
638
        test    eax, eax
638
        je      start_i8254x
639
        je      start_i8254x
639
 
640
 
640
        ret
641
        ret
641
 
642
 
642
align 4
643
align 4
643
start_i8254x:
644
start_i8254x:
644
 
645
 
645
        mov     esi, [ebx + device.mmio_addr]
646
        mov     esi, [ebx + device.mmio_addr]
646
        or      dword[esi + REG_RCTL], RCTL_EN          ; Enable the receiver
647
        or      dword[esi + REG_RCTL], RCTL_EN          ; Enable the receiver
647
 
648
 
648
        xor     eax, eax
649
        xor     eax, eax
649
        mov     [esi + REG_RDTR], eax                   ; Clear the Receive Delay Timer Register
650
        mov     [esi + REG_RDTR], eax                   ; Clear the Receive Delay Timer Register
650
        mov     [esi + REG_RADV], eax                   ; Clear the Receive Interrupt Absolute Delay Timer
651
        mov     [esi + REG_RADV], eax                   ; Clear the Receive Interrupt Absolute Delay Timer
651
        mov     [esi + REG_RSRPD], eax                  ; Clear the Receive Small Packet Detect Interrupt
652
        mov     [esi + REG_RSRPD], eax                  ; Clear the Receive Small Packet Detect Interrupt
652
 
653
 
653
        mov     dword[esi + REG_IMS], 0x1F6DC           ; Enable interrupt types
654
        mov     dword[esi + REG_IMS], 0x1F6DC           ; Enable interrupt types
654
        mov     eax, [esi + REG_ICR]                    ; Clear pending interrupts
655
        mov     eax, [esi + REG_ICR]                    ; Clear pending interrupts
655
 
656
 
656
        mov     [ebx + device.mtu], 1514
657
        mov     [ebx + device.mtu], 1514
657
        mov     [ebx + device.state], ETH_LINK_UNKNOWN  ; Set link state to unknown
658
        mov     [ebx + device.state], ETH_LINK_UNKNOWN  ; Set link state to unknown
658
 
659
 
659
        xor     eax, eax
660
        xor     eax, eax
660
        ret
661
        ret
661
 
662
 
662
 
663
 
663
 
664
 
664
 
665
 
665
align 4
666
align 4
666
read_mac:
667
read_mac:
667
 
668
 
668
        DEBUGF  1,"Read MAC\n"
669
        DEBUGF  1,"Read MAC\n"
669
 
670
 
670
        mov     esi, [ebx + device.mmio_addr]
671
        mov     esi, [ebx + device.mmio_addr]
671
 
672
 
672
        mov     eax, [esi+0x5400]                       ; RAL
673
        mov     eax, [esi+0x5400]                       ; RAL
673
        test    eax, eax
674
        test    eax, eax
674
        jz      .try_eeprom
675
        jz      .try_eeprom
675
 
676
 
676
        mov     dword[ebx + device.mac], eax
677
        mov     dword[ebx + device.mac], eax
677
        mov     eax, [esi+0x5404]                       ; RAH
678
        mov     eax, [esi+0x5404]                       ; RAH
678
        mov     word[ebx + device.mac+4], ax
679
        mov     word[ebx + device.mac+4], ax
679
 
680
 
680
        jmp     .mac_ok
681
        jmp     .mac_ok
681
 
682
 
682
  .try_eeprom:
683
  .try_eeprom:
683
        mov     dword[esi+0x14], 0x00000001
684
        mov     dword[esi+0x14], 0x00000001
684
        mov     eax, [esi+0x14]
685
        mov     eax, [esi+0x14]
685
        shr     eax, 16
686
        shr     eax, 16
686
        mov     word[ebx + device.mac], ax
687
        mov     word[ebx + device.mac], ax
687
 
688
 
688
        mov     dword[esi+0x14], 0x00000101
689
        mov     dword[esi+0x14], 0x00000101
689
        mov     eax, [esi+0x14]
690
        mov     eax, [esi+0x14]
690
        shr     eax, 16
691
        shr     eax, 16
691
        mov     word[ebx + device.mac+2], ax
692
        mov     word[ebx + device.mac+2], ax
692
 
693
 
693
        mov     dword[esi+0x14], 0x00000201
694
        mov     dword[esi+0x14], 0x00000201
694
        mov     eax, [esi+0x14]
695
        mov     eax, [esi+0x14]
695
        shr     eax, 16
696
        shr     eax, 16
696
        mov     word[ebx + device.mac+4], ax
697
        mov     word[ebx + device.mac+4], ax
697
 
698
 
698
  .mac_ok:
699
  .mac_ok:
699
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
700
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
700
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
701
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
701
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
702
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
702
 
703
 
703
        ret
704
        ret
704
 
705
 
705
 
706
 
706
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
707
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
707
;;                                         ;;
708
;;                                         ;;
708
;; Transmit                                ;;
709
;; Transmit                                ;;
709
;;                                         ;;
710
;;                                         ;;
710
;; In: pointer to device structure in ebx  ;;
711
;; In:  ebx = pointer to device structure  ;;
-
 
712
;; Out: eax = 0 on success                 ;;
711
;;                                         ;;
713
;;                                         ;;
712
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
714
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
713
 
715
 
714
proc transmit stdcall bufferptr, buffersize
716
proc transmit stdcall bufferptr
715
 
717
 
716
        pushf
718
        pushf
717
        cli
719
        cli
-
 
720
 
718
 
721
        mov     esi, [bufferptr]
719
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
722
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
720
        mov     eax, [bufferptr]
723
        lea     eax, [esi + NET_BUFF.data]
721
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
724
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
722
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
725
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
723
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
726
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
724
        [eax+13]:2,[eax+12]:2
727
        [eax+13]:2,[eax+12]:2
725
 
728
 
726
        cmp     [buffersize], 1514
729
        cmp     [esi + NET_BUFF.length], 1514
727
        ja      .fail
730
        ja      .fail
728
        cmp     [buffersize], 60
731
        cmp     [esi + NET_BUFF.length], 60
729
        jb      .fail
732
        jb      .fail
730
 
733
 
731
; Program the descriptor (use legacy mode)
734
; Program the descriptor (use legacy mode)
732
        mov     edi, [ebx + device.cur_tx]
735
        mov     edi, [ebx + device.cur_tx]
733
        DEBUGF  1, "Using TX desc: %u\n", edi
736
        DEBUGF  1, "Using TX desc: %u\n", edi
734
        shl     edi, 4                                          ; edi = edi * sizeof.TDESC
737
        shl     edi, 4                                          ; edi = edi * sizeof.TDESC
735
        lea     edi, [ebx + device.tx_desc + edi]
738
        lea     edi, [ebx + device.tx_desc + edi]
-
 
739
        mov     eax, esi
736
        mov     dword[edi + TX_RING_SIZE*sizeof.TDESC], eax     ; Store the data location (for driver)
740
        mov     dword[edi + TX_RING_SIZE*sizeof.TDESC], eax     ; Store the data location (for driver)
-
 
741
        add     eax, [eax + NET_BUFF.offset]
737
        invoke  GetPhysAddr
742
        invoke  GetPhysAddr
738
        mov     [edi + TDESC.addr_l], eax                       ; Data location (for hardware)
743
        mov     [edi + TDESC.addr_l], eax                       ; Data location (for hardware)
739
        mov     [edi + TDESC.addr_h], 0
744
        mov     [edi + TDESC.addr_h], 0
740
 
745
 
741
        mov     ecx, [buffersize]
746
        mov     ecx, [esi + NET_BUFF.length]
742
        or      ecx, TXDESC_EOP + TXDESC_IFCS + TXDESC_RS
747
        or      ecx, TXDESC_EOP + TXDESC_IFCS + TXDESC_RS
743
        mov     [edi + TDESC.length_cso_cmd], ecx
748
        mov     [edi + TDESC.length_cso_cmd], ecx
744
        mov     [edi + TDESC.status], 0
749
        mov     [edi + TDESC.status], 0
745
 
750
 
746
; Tell i8254x wich descriptor(s) we programmed, by moving the tail
751
; Tell i8254x wich descriptor(s) we programmed, by moving the tail
747
        mov     edi, [ebx + device.mmio_addr]
752
        mov     edi, [ebx + device.mmio_addr]
748
        mov     eax, [ebx + device.cur_tx]
753
        mov     eax, [ebx + device.cur_tx]
749
        inc     eax
754
        inc     eax
750
        and     eax, TX_RING_SIZE-1
755
        and     eax, TX_RING_SIZE-1
751
        mov     [ebx + device.cur_tx], eax
756
        mov     [ebx + device.cur_tx], eax
752
        mov     dword[edi + REG_TDT], eax                        ; TDT - Transmit Descriptor Tail
757
        mov     dword[edi + REG_TDT], eax                        ; TDT - Transmit Descriptor Tail
753
 
758
 
754
; Update stats
759
; Update stats
755
        inc     [ebx + device.packets_tx]
760
        inc     [ebx + device.packets_tx]
756
        mov     eax, [buffersize]
761
        mov     eax, [esi + NET_BUFF.length]
757
        add     dword[ebx + device.bytes_tx], eax
762
        add     dword[ebx + device.bytes_tx], eax
758
        adc     dword[ebx + device.bytes_tx + 4], 0
763
        adc     dword[ebx + device.bytes_tx + 4], 0
759
 
764
 
760
        call    clean_tx
765
        call    clean_tx
761
 
766
 
762
        popf
767
        popf
763
        xor     eax, eax
768
        xor     eax, eax
764
        ret
769
        ret
765
 
770
 
766
  .fail:
771
  .fail:
767
        call    clean_tx
772
        call    clean_tx
768
 
773
 
769
        DEBUGF  2,"Send failed\n"
774
        DEBUGF  2,"Send failed\n"
770
        invoke  KernelFree, [bufferptr]
775
        invoke  NetFree, [bufferptr]
771
        popf
776
        popf
772
        or      eax, -1
777
        or      eax, -1
773
        ret
778
        ret
774
 
779
 
775
endp
780
endp
776
 
781
 
777
 
782
 
778
;;;;;;;;;;;;;;;;;;;;;;;
783
;;;;;;;;;;;;;;;;;;;;;;;
779
;;                   ;;
784
;;                   ;;
780
;; Interrupt handler ;;
785
;; Interrupt handler ;;
781
;;                   ;;
786
;;                   ;;
782
;;;;;;;;;;;;;;;;;;;;;;;
787
;;;;;;;;;;;;;;;;;;;;;;;
783
 
788
 
784
align 4
789
align 4
785
int_handler:
790
int_handler:
786
 
791
 
787
        push    ebx esi edi
792
        push    ebx esi edi
788
 
793
 
789
        DEBUGF  1,"INT\n"
794
        DEBUGF  1,"INT\n"
790
;-------------------------------------------
795
;-------------------------------------------
791
; Find pointer of device wich made IRQ occur
796
; Find pointer of device wich made IRQ occur
792
 
797
 
793
        mov     ecx, [devices]
798
        mov     ecx, [devices]
794
        test    ecx, ecx
799
        test    ecx, ecx
795
        jz      .nothing
800
        jz      .nothing
796
        mov     esi, device_list
801
        mov     esi, device_list
797
  .nextdevice:
802
  .nextdevice:
798
        mov     ebx, [esi]
803
        mov     ebx, [esi]
799
        mov     edi, [ebx + device.mmio_addr]
804
        mov     edi, [ebx + device.mmio_addr]
800
        mov     eax, [edi + REG_ICR]
805
        mov     eax, [edi + REG_ICR]
801
        test    eax, eax
806
        test    eax, eax
802
        jnz     .got_it
807
        jnz     .got_it
803
  .continue:
808
  .continue:
804
        add     esi, 4
809
        add     esi, 4
805
        dec     ecx
810
        dec     ecx
806
        jnz     .nextdevice
811
        jnz     .nextdevice
807
  .nothing:
812
  .nothing:
808
        pop     edi esi ebx
813
        pop     edi esi ebx
809
        xor     eax, eax
814
        xor     eax, eax
810
 
815
 
811
        ret
816
        ret
812
 
817
 
813
  .got_it:
818
  .got_it:
814
        DEBUGF  1,"Device: %x Status: %x\n", ebx, eax
819
        DEBUGF  1,"Device: %x Status: %x\n", ebx, eax
815
 
820
 
816
;---------
821
;---------
817
; RX done?
822
; RX done?
818
 
823
 
819
        test    eax, ICR_RXDMT0 + ICR_RXT0
824
        test    eax, ICR_RXDMT0 + ICR_RXT0
820
        jz      .no_rx
825
        jz      .no_rx
821
 
826
 
822
        push    eax ebx
827
        push    eax ebx
823
  .retaddr:
828
  .retaddr:
824
        pop     ebx eax
829
        pop     ebx eax
825
; Get last descriptor addr
830
; Get last descriptor addr
826
        mov     esi, [ebx + device.cur_rx]
831
        mov     esi, [ebx + device.cur_rx]
827
        shl     esi, 4                                  ; esi = esi * sizeof.RDESC
832
        shl     esi, 4                                  ; esi = esi * sizeof.RDESC
828
        lea     esi, [ebx + device.rx_desc + esi]
833
        lea     esi, [ebx + device.rx_desc + esi]
829
        cmp     byte[esi + RDESC.status_h], 0           ; Check status field
834
        cmp     byte[esi + RDESC.status_h], 0           ; Check status field
830
        je      .no_rx
835
        je      .no_rx
831
 
836
 
832
        push    eax ebx
837
        push    eax ebx
833
        push    .retaddr
838
        push    .retaddr
834
        movzx   ecx, word[esi + 8]                      ; Get the packet length
839
        movzx   ecx, word[esi + 8]                      ; Get the packet length
835
        DEBUGF  1,"got %u bytes\n", ecx
840
        DEBUGF  1,"got %u bytes\n", ecx
-
 
841
        mov     eax, [esi + RX_RING_SIZE*sizeof.RDESC]  ; Get packet pointer
836
        push    ecx
842
        push    eax
-
 
843
        mov     [eax + NET_BUFF.length], ecx
-
 
844
        mov     [eax + NET_BUFF.device], ebx
837
        push    dword[esi + RX_RING_SIZE*sizeof.RDESC]  ; Get packet pointer
845
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
838
 
846
 
839
; Update stats
847
; Update stats
840
        add     dword[ebx + device.bytes_rx], ecx
848
        add     dword[ebx + device.bytes_rx], ecx
841
        adc     dword[ebx + device.bytes_rx + 4], 0
849
        adc     dword[ebx + device.bytes_rx + 4], 0
842
        inc     [ebx + device.packets_rx]
850
        inc     [ebx + device.packets_rx]
843
 
851
 
844
; Allocate new descriptor
852
; Allocate new descriptor
845
        push    esi
853
        push    esi
846
        invoke  KernelAlloc, MAX_PKT_SIZE
854
        invoke  NetAlloc, MAX_PKT_SIZE+NET_BUFF.data
847
        pop     esi
855
        pop     esi
848
        test    eax, eax
856
        test    eax, eax
849
        jz      .out_of_mem
857
        jz      .out_of_mem
850
        mov     dword[esi + RX_RING_SIZE*sizeof.RDESC], eax
858
        mov     dword[esi + RX_RING_SIZE*sizeof.RDESC], eax
851
        invoke  GetPhysAddr
859
        invoke  GetPhysAddr
-
 
860
        add     eax, NET_BUFF.data
852
        mov     [esi + RDESC.addr_l], eax
861
        mov     [esi + RDESC.addr_l], eax
853
        mov     [esi + RDESC.status_l], 0
862
        mov     [esi + RDESC.status_l], 0
854
        mov     [esi + RDESC.status_h], 0
863
        mov     [esi + RDESC.status_h], 0
855
 
864
 
856
; Move the receive descriptor tail
865
; Move the receive descriptor tail
857
        mov     esi, [ebx + device.mmio_addr]
866
        mov     esi, [ebx + device.mmio_addr]
858
        mov     eax, [ebx + device.cur_rx]
867
        mov     eax, [ebx + device.cur_rx]
859
        mov     [esi + REG_RDT], eax
868
        mov     [esi + REG_RDT], eax
860
 
869
 
861
; Move to next rx desc
870
; Move to next rx desc
862
        inc     [ebx + device.cur_rx]
871
        inc     [ebx + device.cur_rx]
863
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
872
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
864
 
873
 
865
        jmp     [Eth_input]
874
        jmp     [EthInput]
866
 
875
 
867
  .out_of_mem:
876
  .out_of_mem:
868
        DEBUGF  2,"Out of memory!\n"
877
        DEBUGF  2,"Out of memory!\n"
869
 
878
 
870
; Move to next rx desc
879
; Move to next rx desc
871
        inc     [ebx + device.cur_rx]
880
        inc     [ebx + device.cur_rx]
872
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
881
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
873
 
882
 
874
        jmp     [Eth_input]
883
        jmp     [EthInput]
875
  .no_rx:
884
  .no_rx:
876
 
885
 
877
;--------------
886
;--------------
878
; Link Changed?
887
; Link Changed?
879
 
888
 
880
        test    eax, ICR_LSC
889
        test    eax, ICR_LSC
881
        jz      .no_link
890
        jz      .no_link
882
 
891
 
883
        DEBUGF  2,"Link Changed\n"
892
        DEBUGF  2,"Link Changed\n"
884
 
893
 
885
  .no_link:
894
  .no_link:
886
 
895
 
887
;---------------
896
;---------------
888
; Transmit done?
897
; Transmit done?
889
 
898
 
890
        test    eax, ICR_TXDW
899
        test    eax, ICR_TXDW
891
        jz      .no_tx
900
        jz      .no_tx
892
 
901
 
893
        DEBUGF  1,"Transmit done\n"
902
        DEBUGF  1,"Transmit done\n"
894
 
903
 
895
;        call    clean_tx
904
;        call    clean_tx
896
 
905
 
897
  .no_tx:
906
  .no_tx:
898
        pop     edi esi ebx
907
        pop     edi esi ebx
899
        xor     eax, eax
908
        xor     eax, eax
900
        inc     eax
909
        inc     eax
901
        ret
910
        ret
902
 
911
 
903
 
912
 
904
 
913
 
905
clean_tx:
914
clean_tx:
906
 
915
 
907
  .txdesc_loop:
916
  .txdesc_loop:
908
        mov     edi, [ebx + device.last_tx]
917
        mov     edi, [ebx + device.last_tx]
909
        shl     edi, 4                                  ; edi = edi * sizeof.TDESC
918
        shl     edi, 4                                  ; edi = edi * sizeof.TDESC
910
        lea     edi, [ebx + device.tx_desc + edi]
919
        lea     edi, [ebx + device.tx_desc + edi]
911
        test    [edi + TDESC.status], TXDESC_DD         ; Descriptor done?
920
        test    [edi + TDESC.status], TXDESC_DD         ; Descriptor done?
912
        jz      .no_tx
921
        jz      .no_tx
913
        cmp     dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
922
        cmp     dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
914
        je      .no_tx
923
        je      .no_tx
915
 
924
 
916
        DEBUGF  1,"Cleaning up TX desc: 0x%x\n", edi
925
        DEBUGF  1,"Cleaning up TX desc: 0x%x\n", edi
917
 
926
 
918
        push    ebx
927
        push    ebx
919
        push    dword[edi + TX_RING_SIZE*sizeof.TDESC]
928
        push    dword[edi + TX_RING_SIZE*sizeof.TDESC]
920
        mov     dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
929
        mov     dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
921
        invoke  KernelFree
930
        invoke  NetFree
922
        pop     ebx
931
        pop     ebx
923
 
932
 
924
        inc     [ebx + device.last_tx]
933
        inc     [ebx + device.last_tx]
925
        and     [ebx + device.last_tx], TX_RING_SIZE-1
934
        and     [ebx + device.last_tx], TX_RING_SIZE-1
926
        jmp     .txdesc_loop
935
        jmp     .txdesc_loop
927
 
936
 
928
  .no_tx:
937
  .no_tx:
929
 
938
 
930
        ret
939
        ret
931
 
940
 
932
 
941
 
933
 
942
 
934
 
943
 
935
; End of code
944
; End of code
936
 
945
 
937
data fixups
946
data fixups
938
end data
947
end data
939
 
948
 
940
include '../peimport.inc'
949
include '../peimport.inc'
941
 
950
 
942
include_debug_strings
951
include_debug_strings
943
my_service      db 'I8254X', 0          ; max 16 chars include zero
952
my_service      db 'I8254X', 0          ; max 16 chars include zero
944
 
953
 
945
align 4
954
align 4
946
devices         dd 0
955
devices         dd 0
947
device_list     rd MAX_DEVICES          ; This list contains all pointers to device structures the driver is handling
956
device_list     rd MAX_DEVICES          ; This list contains all pointers to device structures the driver is handling