Subversion Repositories Kolibri OS

Rev

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

Rev 5127 Rev 5363
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2014. 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
;;  Realtek 8139 driver for KolibriOS                              ;;
6
;;  Realtek 8139 driver for KolibriOS                              ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  based on RTL8139.asm driver for menuetos                       ;;
8
;;  based on RTL8139.asm driver for menuetos                       ;;
9
;;  and realtek8139.asm for SolarOS by Eugen Brasoveanu            ;;
9
;;  and realtek8139.asm for SolarOS by Eugen Brasoveanu            ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;    Written by hidnplayr@kolibrios.org                           ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
17
 
18
format PE DLL native
18
format PE DLL native
19
entry START
19
entry START
20
 
20
 
21
        CURRENT_API             = 0x0200
21
        CURRENT_API             = 0x0200
22
        COMPATIBLE_API          = 0x0100
22
        COMPATIBLE_API          = 0x0100
23
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
23
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
24
 
24
 
25
        MAX_DEVICES             = 16
25
        MAX_DEVICES             = 16
26
 
26
 
27
        RBLEN                   = 3     ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
27
        RBLEN                   = 3     ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
28
 
28
 
29
        TXRR                    = 8     ; total retries = 16+(TXRR*16)
29
        TXRR                    = 8     ; total retries = 16+(TXRR*16)
30
        TX_MXDMA                = 6     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048
30
        TX_MXDMA                = 6     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048
31
        ERTXTH                  = 8     ; in unit of 32 bytes e.g:(8*32)=256
31
        ERTXTH                  = 8     ; in unit of 32 bytes e.g:(8*32)=256
32
        RX_MXDMA                = 7     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited
32
        RX_MXDMA                = 7     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited
33
        RXFTH                   = 7     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold
33
        RXFTH                   = 7     ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold
34
 
34
 
35
        __DEBUG__               = 1
35
        __DEBUG__               = 1
36
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
36
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
37
 
37
 
38
section '.flat' readable writable executable
38
section '.flat' readable writable executable
39
 
39
 
40
include '../proc32.inc'
40
include '../proc32.inc'
41
include '../struct.inc'
41
include '../struct.inc'
42
include '../macros.inc'
42
include '../macros.inc'
43
include '../fdo.inc'
43
include '../fdo.inc'
44
include '../netdrv.inc'
44
include '../netdrv.inc'
45
 
45
 
46
        REG_IDR0                = 0x00
46
        REG_IDR0                = 0x00
47
        REG_MAR0                = 0x08 ; multicast filter register 0
47
        REG_MAR0                = 0x08 ; multicast filter register 0
48
        REG_MAR4                = 0x0c ; multicast filter register 4
48
        REG_MAR4                = 0x0c ; multicast filter register 4
49
        REG_TSD0                = 0x10 ; transmit status of descriptor
49
        REG_TSD0                = 0x10 ; transmit status of descriptor
50
        REG_TSAD0               = 0x20 ; transmit start address of descriptor
50
        REG_TSAD0               = 0x20 ; transmit start address of descriptor
51
        REG_RBSTART             = 0x30 ; RxBuffer start address
51
        REG_RBSTART             = 0x30 ; RxBuffer start address
52
        REG_COMMAND             = 0x37 ; command register
52
        REG_COMMAND             = 0x37 ; command register
53
        REG_CAPR                = 0x38 ; current address of packet read (word) R/W
53
        REG_CAPR                = 0x38 ; current address of packet read (word) R/W
54
        REG_IMR                 = 0x3c ; interrupt mask register
54
        REG_IMR                 = 0x3c ; interrupt mask register
55
        REG_ISR                 = 0x3e ; interrupt status register
55
        REG_ISR                 = 0x3e ; interrupt status register
56
        REG_TXCONFIG            = 0x40 ; transmit configuration register
56
        REG_TXCONFIG            = 0x40 ; transmit configuration register
57
        REG_RXCONFIG            = 0x44 ; receive configuration register 0
57
        REG_RXCONFIG            = 0x44 ; receive configuration register 0
58
        REG_MPC                 = 0x4c ; missed packet counter
58
        REG_MPC                 = 0x4c ; missed packet counter
59
        REG_9346CR              = 0x50 ; serial eeprom 93C46 command register
59
        REG_9346CR              = 0x50 ; serial eeprom 93C46 command register
60
        REG_CONFIG1             = 0x52 ; configuration register 1
60
        REG_CONFIG1             = 0x52 ; configuration register 1
61
        REG_MSR                 = 0x58
61
        REG_MSR                 = 0x58
62
        REG_CONFIG4             = 0x5a ; configuration register 4
62
        REG_CONFIG4             = 0x5a ; configuration register 4
63
        REG_HLTCLK              = 0x5b ; undocumented halt clock register
63
        REG_HLTCLK              = 0x5b ; undocumented halt clock register
64
        REG_BMCR                = 0x62 ; basic mode control register
64
        REG_BMCR                = 0x62 ; basic mode control register
65
        REG_ANAR                = 0x66 ; auto negotiation advertisement register
65
        REG_ANAR                = 0x66 ; auto negotiation advertisement register
66
        REG_9346CR_WE           = 11b shl 6
66
        REG_9346CR_WE           = 11b shl 6
67
 
67
 
68
        BIT_RUNT                = 4 ; total packet length < 64 bytes
68
        BIT_RUNT                = 4 ; total packet length < 64 bytes
69
        BIT_LONG                = 3 ; total packet length > 4k
69
        BIT_LONG                = 3 ; total packet length > 4k
70
        BIT_CRC                 = 2 ; crc error occured
70
        BIT_CRC                 = 2 ; crc error occured
71
        BIT_FAE                 = 1 ; frame alignment error occured
71
        BIT_FAE                 = 1 ; frame alignment error occured
72
        BIT_ROK                 = 0 ; received packet is ok
72
        BIT_ROK                 = 0 ; received packet is ok
73
 
73
 
74
        BIT_RST                 = 4 ; reset bit
74
        BIT_RST                 = 4 ; reset bit
75
        BIT_RE                  = 3 ; receiver enabled
75
        BIT_RE                  = 3 ; receiver enabled
76
        BIT_TE                  = 2 ; transmitter enabled
76
        BIT_TE                  = 2 ; transmitter enabled
77
        BUFE                    = 1 ; rx buffer is empty, no packet stored
77
        BUFE                    = 1 ; rx buffer is empty, no packet stored
78
 
78
 
79
        BIT_ISR_TOK             = 2 ; transmit ok
79
        BIT_ISR_TOK             = 2 ; transmit ok
80
        BIT_ISR_RER             = 1 ; receive error interrupt
80
        BIT_ISR_RER             = 1 ; receive error interrupt
81
        BIT_ISR_ROK             = 0 ; receive ok
81
        BIT_ISR_ROK             = 0 ; receive ok
82
 
82
 
83
        BIT_TX_MXDMA            = 8 ; Max DMA burst size per Tx DMA burst
83
        BIT_TX_MXDMA            = 8 ; Max DMA burst size per Tx DMA burst
84
        BIT_TXRR                = 4 ; Tx Retry count 16+(TXRR*16)
84
        BIT_TXRR                = 4 ; Tx Retry count 16+(TXRR*16)
85
 
85
 
86
        BIT_RXFTH               = 13 ; Rx fifo threshold
86
        BIT_RXFTH               = 13 ; Rx fifo threshold
87
        BIT_RBLEN               = 11 ; Ring buffer length indicator
87
        BIT_RBLEN               = 11 ; Ring buffer length indicator
88
        BIT_RX_MXDMA            = 8 ; Max DMA burst size per Rx DMA burst
88
        BIT_RX_MXDMA            = 8 ; Max DMA burst size per Rx DMA burst
89
        BIT_NOWRAP              = 7 ; transfered data wrapping
89
        BIT_NOWRAP              = 7 ; transfered data wrapping
90
        BIT_9356SEL             = 6 ; eeprom selector 9346/9356
90
        BIT_9356SEL             = 6 ; eeprom selector 9346/9356
91
        BIT_AER                 = 5 ; accept error packets
91
        BIT_AER                 = 5 ; accept error packets
92
        BIT_AR                  = 4 ; accept runt packets
92
        BIT_AR                  = 4 ; accept runt packets
93
        BIT_AB                  = 3 ; accept broadcast packets
93
        BIT_AB                  = 3 ; accept broadcast packets
94
        BIT_AM                  = 2 ; accept multicast packets
94
        BIT_AM                  = 2 ; accept multicast packets
95
        BIT_APM                 = 1 ; accept physical match packets
95
        BIT_APM                 = 1 ; accept physical match packets
96
        BIT_AAP                 = 0 ; accept all packets
96
        BIT_AAP                 = 0 ; accept all packets
97
 
97
 
98
        BIT_93C46_EEM1          = 7 ; RTL8139 eeprom operating mode1
98
        BIT_93C46_EEM1          = 7 ; RTL8139 eeprom operating mode1
99
        BIT_93C46_EEM0          = 6 ; RTL8139 eeprom operating mode0
99
        BIT_93C46_EEM0          = 6 ; RTL8139 eeprom operating mode0
100
        BIT_93C46_EECS          = 3 ; chip select
100
        BIT_93C46_EECS          = 3 ; chip select
101
        BIT_93C46_EESK          = 2 ; serial data clock
101
        BIT_93C46_EESK          = 2 ; serial data clock
102
        BIT_93C46_EEDI          = 1 ; serial data input
102
        BIT_93C46_EEDI          = 1 ; serial data input
103
        BIT_93C46_EEDO          = 0 ; serial data output
103
        BIT_93C46_EEDO          = 0 ; serial data output
104
 
104
 
105
        BIT_LWACT               = 4 ; see REG_CONFIG1
105
        BIT_LWACT               = 4 ; see REG_CONFIG1
106
        BIT_SLEEP               = 1 ; sleep bit at older chips
106
        BIT_SLEEP               = 1 ; sleep bit at older chips
107
        BIT_PWRDWN              = 0 ; power down bit at older chips
107
        BIT_PWRDWN              = 0 ; power down bit at older chips
108
        BIT_PMEn                = 0 ; power management enabled
108
        BIT_PMEn                = 0 ; power management enabled
109
 
109
 
110
        BIT_LWPTN               = 2 ; see REG_CONFIG4
110
        BIT_LWPTN               = 2 ; see REG_CONFIG4
111
 
111
 
112
        BIT_ERTXTH              = 16 ; early TX threshold
112
        BIT_ERTXTH              = 16 ; early TX threshold
113
        BIT_TOK                 = 15 ; transmit ok
113
        BIT_TOK                 = 15 ; transmit ok
114
        BIT_OWN                 = 13 ; tx DMA operation is completed
114
        BIT_OWN                 = 13 ; tx DMA operation is completed
115
 
115
 
116
        BIT_ANE                 = 12 ; auto negotiation enable
116
        BIT_ANE                 = 12 ; auto negotiation enable
117
 
117
 
118
        BIT_TXFD                = 8 ; 100base-T full duplex
118
        BIT_TXFD                = 8 ; 100base-T full duplex
119
        BIT_TX                  = 7 ; 100base-T
119
        BIT_TX                  = 7 ; 100base-T
120
        BIT_10FD                = 6 ; 10base-T full duplex
120
        BIT_10FD                = 6 ; 10base-T full duplex
121
        BIT_10                  = 5 ; 10base-T
121
        BIT_10                  = 5 ; 10base-T
122
        BIT_SELECTOR            = 0 ; binary encoded selector CSMA/CD=00001
122
        BIT_SELECTOR            = 0 ; binary encoded selector CSMA/CD=00001
123
 
123
 
124
        BIT_IFG1                = 25
124
        BIT_IFG1                = 25
125
        BIT_IFG0                = 24
125
        BIT_IFG0                = 24
126
 
126
 
127
        RX_CONFIG               = (RBLEN shl BIT_RBLEN) or \
127
        RX_CONFIG               = (RBLEN shl BIT_RBLEN) or \
128
                                  (RX_MXDMA shl BIT_RX_MXDMA) or \
128
                                  (RX_MXDMA shl BIT_RX_MXDMA) or \
129
                                  (1 shl BIT_NOWRAP) or \
129
                                  (1 shl BIT_NOWRAP) or \
130
                                  (RXFTH shl BIT_RXFTH) or\
130
                                  (RXFTH shl BIT_RXFTH) or\
131
                                  (1 shl BIT_AB) or \                   ; Accept broadcast packets
131
                                  (1 shl BIT_AB) or \                   ; Accept broadcast packets
132
                                  (1 shl BIT_APM) or \                  ; Accept physical match packets
132
                                  (1 shl BIT_APM) or \                  ; Accept physical match packets
133
                                  (1 shl BIT_AER) or \                  ; Accept error packets
133
                                  (1 shl BIT_AER) or \                  ; Accept error packets
134
                                  (1 shl BIT_AR) or \                   ; Accept Runt packets (smaller then 64 bytes)
134
                                  (1 shl BIT_AR) or \                   ; Accept Runt packets (smaller then 64 bytes)
135
                                  (1 shl BIT_AM)                        ; Accept multicast packets
135
                                  (1 shl BIT_AM)                        ; Accept multicast packets
136
 
136
 
137
        RX_BUFFER_SIZE          = (8192 shl RBLEN);+16+1500
137
        RX_BUFFER_SIZE          = (8192 shl RBLEN);+16+1500
138
        NUM_TX_DESC             = 4                                     ; not user selectable
138
        NUM_TX_DESC             = 4                                     ; not user selectable
139
 
139
 
140
        EE_93C46_REG_ETH_ID     = 7 ; MAC offset
140
        EE_93C46_REG_ETH_ID     = 7 ; MAC offset
141
        EE_93C46_READ_CMD       = (6 shl 6) ; 110b + 6bit address
141
        EE_93C46_READ_CMD       = (6 shl 6) ; 110b + 6bit address
142
        EE_93C56_READ_CMD       = (6 shl 8) ; 110b + 8bit address
142
        EE_93C56_READ_CMD       = (6 shl 8) ; 110b + 8bit address
143
        EE_93C46_CMD_LENGTH     = 9  ; start bit + cmd + 6bit address
143
        EE_93C46_CMD_LENGTH     = 9  ; start bit + cmd + 6bit address
144
        EE_93C56_CMD_LENGTH     = 11 ; start bit + cmd + 8bit ddress
144
        EE_93C56_CMD_LENGTH     = 11 ; start bit + cmd + 8bit ddress
145
 
145
 
146
        VER_RTL8139             = 1100000b
146
        VER_RTL8139             = 1100000b
147
        VER_RTL8139A            = 1110000b
147
        VER_RTL8139A            = 1110000b
148
        VER_RTL8139AG           = 1110100b
148
        VER_RTL8139AG           = 1110100b
149
        VER_RTL8139B            = 1111000b
149
        VER_RTL8139B            = 1111000b
150
        VER_RTL8130             = VER_RTL8139B
150
        VER_RTL8130             = VER_RTL8139B
151
        VER_RTL8139C            = 1110100b
151
        VER_RTL8139C            = 1110100b
152
        VER_RTL8100             = 1111010b
152
        VER_RTL8100             = 1111010b
153
        VER_RTL8100B            = 1110101b
153
        VER_RTL8100B            = 1110101b
154
        VER_RTL8139D            = VER_RTL8100B
154
        VER_RTL8139D            = VER_RTL8100B
155
        VER_RTL8139CP           = 1110110b
155
        VER_RTL8139CP           = 1110110b
156
        VER_RTL8101             = 1110111b
156
        VER_RTL8101             = 1110111b
157
 
157
 
158
        IDX_RTL8139             = 0
158
        IDX_RTL8139             = 0
159
        IDX_RTL8139A            = 1
159
        IDX_RTL8139A            = 1
160
        IDX_RTL8139B            = 2
160
        IDX_RTL8139B            = 2
161
        IDX_RTL8139C            = 3
161
        IDX_RTL8139C            = 3
162
        IDX_RTL8100             = 4
162
        IDX_RTL8100             = 4
163
        IDX_RTL8139D            = 5
163
        IDX_RTL8139D            = 5
164
        IDX_RTL8139D            = 6
164
        IDX_RTL8139D            = 6
165
        IDX_RTL8101             = 7
165
        IDX_RTL8101             = 7
166
 
166
 
167
        ISR_SERR                = 1 shl 15
167
        ISR_SERR                = 1 shl 15
168
        ISR_TIMEOUT             = 1 shl 14
168
        ISR_TIMEOUT             = 1 shl 14
169
        ISR_LENCHG              = 1 shl 13
169
        ISR_LENCHG              = 1 shl 13
170
        ISR_FIFOOVW             = 1 shl 6
170
        ISR_FIFOOVW             = 1 shl 6
171
        ISR_PUN                 = 1 shl 5
171
        ISR_PUN                 = 1 shl 5
172
        ISR_RXOVW               = 1 shl 4
172
        ISR_RXOVW               = 1 shl 4
173
        ISR_TER                 = 1 shl 3
173
        ISR_TER                 = 1 shl 3
174
        ISR_TOK                 = 1 shl 2
174
        ISR_TOK                 = 1 shl 2
175
        ISR_RER                 = 1 shl 1
175
        ISR_RER                 = 1 shl 1
176
        ISR_ROK                 = 1 shl 0
176
        ISR_ROK                 = 1 shl 0
177
 
177
 
178
        INTERRUPT_MASK          = ISR_ROK or \
178
        INTERRUPT_MASK          = ISR_ROK or \
179
                                  ISR_RER or \
179
                                  ISR_RER or \
180
                                  ISR_TOK or \
180
                                  ISR_TOK or \
181
                                  ISR_TER or \
181
                                  ISR_TER or \
182
                                  ISR_RXOVW or \
182
                                  ISR_RXOVW or \
183
                                  ISR_PUN or \
183
                                  ISR_PUN or \
184
                                  ISR_FIFOOVW or \
184
                                  ISR_FIFOOVW or \
185
                                  ISR_LENCHG or \
185
                                  ISR_LENCHG or \
186
                                  ISR_TIMEOUT or \
186
                                  ISR_TIMEOUT or \
187
                                  ISR_SERR
187
                                  ISR_SERR
188
 
188
 
189
        TSR_OWN                 = 1 shl 13
189
        TSR_OWN                 = 1 shl 13
190
        TSR_TUN                 = 1 shl 14
190
        TSR_TUN                 = 1 shl 14
191
        TSR_TOK                 = 1 shl 15
191
        TSR_TOK                 = 1 shl 15
192
 
192
 
193
        TSR_CDH                 = 1 shl 28
193
        TSR_CDH                 = 1 shl 28
194
        TSR_OWC                 = 1 shl 29
194
        TSR_OWC                 = 1 shl 29
195
        TSR_TABT                = 1 shl 30
195
        TSR_TABT                = 1 shl 30
196
        TSR_CRS                 = 1 shl 31
196
        TSR_CRS                 = 1 shl 31
197
 
197
 
198
 
198
 
199
struct  device          ETH_DEVICE
199
struct  device          ETH_DEVICE
200
 
200
 
201
        io_addr         dd ?
201
        io_addr         dd ?
202
        pci_bus         dd ?
202
        pci_bus         dd ?
203
        pci_dev         dd ?
203
        pci_dev         dd ?
204
        irq_line        db ?
204
        irq_line        db ?
205
                        rb 3    ; align 4
205
                        rb 3    ; align 4
206
 
206
 
207
        rx_buffer       dd ?
207
        rx_buffer       dd ?
208
        rx_data_offset  dd ?
208
        rx_data_offset  dd ?
209
        curr_tx_desc    db ?
209
        curr_tx_desc    db ?
210
        hw_ver_id       db ?
210
        hw_ver_id       db ?
211
                        rb 2    ; align 4
211
                        rb 2    ; align 4
212
 
212
 
213
        TX_DESC         rd NUM_TX_DESC
213
        TX_DESC         rd NUM_TX_DESC
214
 
214
 
215
ends
215
ends
216
 
216
 
217
 
217
 
218
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
218
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
219
;;                        ;;
219
;;                        ;;
220
;; proc START             ;;
220
;; proc START             ;;
221
;;                        ;;
221
;;                        ;;
222
;; (standard driver proc) ;;
222
;; (standard driver proc) ;;
223
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
223
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
224
 
224
 
225
proc START c, reason:dword, cmdline:dword
225
proc START c, reason:dword, cmdline:dword
226
 
226
 
227
        cmp     [reason], DRV_ENTRY
227
        cmp     [reason], DRV_ENTRY
228
        jne     .fail
228
        jne     .fail
229
 
229
 
230
        DEBUGF  2,"Loading driver\n"
230
        DEBUGF  2,"Loading driver\n"
231
        invoke  RegService, my_service, service_proc
231
        invoke  RegService, my_service, service_proc
232
        ret
232
        ret
233
 
233
 
234
  .fail:
234
  .fail:
235
        xor     eax, eax
235
        xor     eax, eax
236
        ret
236
        ret
237
 
237
 
238
endp
238
endp
239
 
239
 
240
 
240
 
241
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
242
;;                        ;;
242
;;                        ;;
243
;; proc SERVICE_PROC      ;;
243
;; proc SERVICE_PROC      ;;
244
;;                        ;;
244
;;                        ;;
245
;; (standard driver proc) ;;
245
;; (standard driver proc) ;;
246
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
246
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
247
 
247
 
248
proc service_proc stdcall, ioctl:dword
248
proc service_proc stdcall, ioctl:dword
249
 
249
 
250
        mov     edx, [ioctl]
250
        mov     edx, [ioctl]
251
        mov     eax, [edx + IOCTL.io_code]
251
        mov     eax, [edx + IOCTL.io_code]
252
 
252
 
253
;------------------------------------------------------
253
;------------------------------------------------------
254
 
254
 
255
        cmp     eax, 0 ;SRV_GETVERSION
255
        cmp     eax, 0 ;SRV_GETVERSION
256
        jne     @F
256
        jne     @F
257
 
257
 
258
        cmp     [edx + IOCTL.out_size], 4
258
        cmp     [edx + IOCTL.out_size], 4
259
        jb      .fail
259
        jb      .fail
260
        mov     eax, [edx + IOCTL.output]
260
        mov     eax, [edx + IOCTL.output]
261
        mov     [eax], dword API_VERSION
261
        mov     [eax], dword API_VERSION
262
 
262
 
263
        xor     eax, eax
263
        xor     eax, eax
264
        ret
264
        ret
265
 
265
 
266
;------------------------------------------------------
266
;------------------------------------------------------
267
  @@:
267
  @@:
268
        cmp     eax, 1 ;SRV_HOOK
268
        cmp     eax, 1 ;SRV_HOOK
269
        jne     .fail
269
        jne     .fail
270
 
270
 
271
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
271
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
272
        jb      .fail
272
        jb      .fail
273
 
273
 
274
        mov     eax, [edx + IOCTL.input]
274
        mov     eax, [edx + IOCTL.input]
275
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
275
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
276
        jne     .fail                                   ; other types arent supported for this card yet
276
        jne     .fail                                   ; other types arent supported for this card yet
277
 
277
 
278
; check if the device is already listed
278
; check if the device is already listed
279
 
279
 
280
        mov     esi, device_list
280
        mov     esi, device_list
281
        mov     ecx, [devices]
281
        mov     ecx, [devices]
282
        test    ecx, ecx
282
        test    ecx, ecx
283
        jz      .firstdevice
283
        jz      .firstdevice
284
 
284
 
285
        mov     ax, [eax+1]                             ; get the pci bus and device numbers
285
        mov     ax, [eax+1]                             ; get the pci bus and device numbers
286
  .nextdevice:
286
  .nextdevice:
287
        mov     ebx, [esi]
287
        mov     ebx, [esi]
288
        cmp     al, byte[ebx + device.pci_bus]
288
        cmp     al, byte[ebx + device.pci_bus]
289
        jne     @f
289
        jne     @f
290
        cmp     ah, byte[ebx + device.pci_dev]
290
        cmp     ah, byte[ebx + device.pci_dev]
291
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
291
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
292
       @@:
292
       @@:
293
        add     esi, 4
293
        add     esi, 4
294
        loop    .nextdevice
294
        loop    .nextdevice
295
 
295
 
296
 
296
 
297
; This device doesnt have its own eth_device structure yet, lets create one
297
; This device doesnt have its own eth_device structure yet, lets create one
298
  .firstdevice:
298
  .firstdevice:
299
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
299
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
300
        jae     .fail
300
        jae     .fail
301
 
301
 
302
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
302
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
303
 
303
 
304
; Fill in the direct call addresses into the struct
304
; Fill in the direct call addresses into the struct
305
 
305
 
306
        mov     [ebx + device.reset], reset
306
        mov     [ebx + device.reset], reset
307
        mov     [ebx + device.transmit], transmit
307
        mov     [ebx + device.transmit], transmit
308
        mov     [ebx + device.unload], unload
308
        mov     [ebx + device.unload], unload
309
        mov     [ebx + device.name], my_service
309
        mov     [ebx + device.name], my_service
310
 
310
 
311
; save the pci bus and device numbers
311
; save the pci bus and device numbers
312
 
312
 
313
        mov     eax, [edx + IOCTL.input]
313
        mov     eax, [edx + IOCTL.input]
314
        movzx   ecx, byte[eax+1]
314
        movzx   ecx, byte[eax+1]
315
        mov     [ebx + device.pci_bus], ecx
315
        mov     [ebx + device.pci_bus], ecx
316
        movzx   ecx, byte[eax+2]
316
        movzx   ecx, byte[eax+2]
317
        mov     [ebx + device.pci_dev], ecx
317
        mov     [ebx + device.pci_dev], ecx
318
 
318
 
319
; Now, it's time to find the base io addres of the PCI device
319
; Now, it's time to find the base io addres of the PCI device
320
 
320
 
321
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
321
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
322
        mov     [ebx + device.io_addr], eax
322
        mov     [ebx + device.io_addr], eax
323
 
323
 
324
; We've found the io address, find IRQ now
324
; We've found the io address, find IRQ now
325
 
325
 
326
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
326
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
327
        mov     [ebx + device.irq_line], al
327
        mov     [ebx + device.irq_line], al
328
 
328
 
329
        DEBUGF  1, "Hooking into device, dev:%x, bus:%x, irq:%x, I/O addr:%x\n",\
329
        DEBUGF  1, "Hooking into device, dev:%x, bus:%x, irq:%x, I/O addr:%x\n",\
330
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
330
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
331
 
331
 
332
; Allocate the receive buffer
332
; Allocate the receive buffer
333
 
333
 
334
        invoke  CreateRingBuffer, dword (RX_BUFFER_SIZE), dword PG_SW
334
        invoke  CreateRingBuffer, dword (RX_BUFFER_SIZE), dword PG_SW
335
        test    eax, eax
335
        test    eax, eax
336
        jz      .err
336
        jz      .err
337
        mov     [ebx + device.rx_buffer], eax
337
        mov     [ebx + device.rx_buffer], eax
338
 
338
 
339
; Ok, the eth_device structure is ready, let's probe the device
339
; Ok, the eth_device structure is ready, let's probe the device
340
 
340
 
341
        call    probe                                                   ; this function will output in eax
341
        call    probe                                                   ; this function will output in eax
342
        test    eax, eax
342
        test    eax, eax
343
        jnz     .err                                                    ; If an error occured, exit
343
        jnz     .err                                                    ; If an error occured, exit
344
 
344
 
345
        mov     eax, [devices]                                          ; Add the device structure to our device list
345
        mov     eax, [devices]                                          ; Add the device structure to our device list
346
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
346
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
347
        inc     [devices]                                               ;
347
        inc     [devices]                                               ;
348
 
348
 
349
        call    reset
349
        call    reset
350
        test    eax, eax
350
        test    eax, eax
351
        jnz     .destroy
351
        jnz     .destroy
352
 
352
 
353
        mov     [ebx + device.type], NET_TYPE_ETH
353
        mov     [ebx + device.type], NET_TYPE_ETH
354
        invoke  NetRegDev
354
        invoke  NetRegDev
355
 
355
 
356
        cmp     eax, -1
356
        cmp     eax, -1
357
        je      .destroy
357
        je      .destroy
358
 
358
 
359
        ret
359
        ret
360
 
360
 
361
; If the device was already loaded, find the device number and return it in eax
361
; If the device was already loaded, find the device number and return it in eax
362
 
362
 
363
  .find_devicenum:
363
  .find_devicenum:
364
        DEBUGF  1, "Trying to find device number of already registered device\n"
364
        DEBUGF  1, "Trying to find device number of already registered device\n"
365
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
365
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
366
                                                                        ; into a device number in edi
366
                                                                        ; into a device number in edi
367
        mov     eax, edi                                                ; Application wants it in eax instead
367
        mov     eax, edi                                                ; Application wants it in eax instead
368
        DEBUGF  1, "Kernel says: %u\n", eax
368
        DEBUGF  1, "Kernel says: %u\n", eax
369
        ret
369
        ret
370
 
370
 
371
; If an error occured, remove all allocated data and exit (returning -1 in eax)
371
; If an error occured, remove all allocated data and exit (returning -1 in eax)
372
 
372
 
373
  .destroy:
373
  .destroy:
374
        ; todo: unregister device from device_list
374
        ; todo: unregister device from device_list
375
        ; todo: reset device into virgin state
375
        ; todo: reset device into virgin state
376
 
376
 
377
  .err:
377
  .err:
378
        DEBUGF  2, "Error, removing all data !\n"
378
        DEBUGF  2, "Error, removing all data !\n"
379
        invoke  KernelFree, [ebx + device.rx_buffer]
379
        invoke  KernelFree, [ebx + device.rx_buffer]
380
        invoke  KernelFree, ebx
380
        invoke  KernelFree, ebx
381
 
381
 
382
  .fail:
382
  .fail:
383
        or      eax, -1
383
        or      eax, -1
384
        ret
384
        ret
385
 
385
 
386
;------------------------------------------------------
386
;------------------------------------------------------
387
endp
387
endp
388
 
388
 
389
 
389
 
390
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
390
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
391
;;                                                                        ;;
391
;;                                                                        ;;
392
;;        Actual Hardware dependent code starts here                      ;;
392
;;        Actual Hardware dependent code starts here                      ;;
393
;;                                                                        ;;
393
;;                                                                        ;;
394
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
394
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
395
 
395
 
396
align 4
396
align 4
397
unload:
397
unload:
398
        ; TODO: (in this particular order)
398
        ; TODO: (in this particular order)
399
        ;
399
        ;
400
        ; - Stop the device
400
        ; - Stop the device
401
        ; - Detach int handler
401
        ; - Detach int handler
402
        ; - Remove device from local list (RTL8139_LIST)
402
        ; - Remove device from local list (RTL8139_LIST)
403
        ; - call unregister function in kernel
403
        ; - call unregister function in kernel
404
        ; - Remove all allocated structures and buffers the card used
404
        ; - Remove all allocated structures and buffers the card used
405
 
405
 
406
        or      eax, -1
406
        or      eax, -1
407
 
407
 
408
ret
408
ret
409
 
409
 
410
 
410
 
411
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
411
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
412
;;
412
;;
413
;;  probe: enables the device (if it really is RTL8139)
413
;;  probe: enables the device (if it really is RTL8139)
414
;;
414
;;
415
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
415
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
416
 
416
 
417
align 4
417
align 4
418
probe:
418
probe:
419
        DEBUGF  1, "Probing\n"
419
        DEBUGF  1, "Probing\n"
420
 
420
 
421
; Make the device a bus master
421
; Make the device a bus master
422
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
422
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
423
        or      al, PCI_CMD_MASTER
423
        or      al, PCI_CMD_MASTER
424
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
424
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
425
 
425
 
426
; get chip version
426
; get chip version
427
        set_io  [ebx + device.io_addr], 0
427
        set_io  [ebx + device.io_addr], 0
428
        set_io  [ebx + device.io_addr], REG_TXCONFIG + 2
428
        set_io  [ebx + device.io_addr], REG_TXCONFIG + 2
429
        in      ax, dx
429
        in      ax, dx
430
        shr     ah, 2
430
        shr     ah, 2
431
        shr     ax, 6
431
        shr     ax, 6
432
        and     al, 01111111b
432
        and     al, 01111111b
433
 
433
 
434
; now find it in our array
434
; now find it in our array
435
        mov     ecx, HW_VER_ARRAY_SIZE-1
435
        mov     ecx, HW_VER_ARRAY_SIZE-1
436
  .chip_ver_loop:
436
  .chip_ver_loop:
437
        cmp     al, [hw_ver_array + ecx]
437
        cmp     al, [hw_ver_array + ecx]
438
        je      .chip_ver_found
438
        je      .chip_ver_found
439
        dec     ecx
439
        dec     ecx
440
        jns     .chip_ver_loop
440
        jns     .chip_ver_loop
441
  .unknown:
441
  .unknown:
442
        mov     ecx, 8
442
        mov     ecx, 8
443
  .chip_ver_found:
443
  .chip_ver_found:
444
        cmp     ecx, 8
444
        cmp     ecx, 8
445
        ja      .unknown
445
        ja      .unknown
446
 
446
 
447
        mov     [ebx + device.hw_ver_id], cl
447
        mov     [ebx + device.hw_ver_id], cl
448
 
448
 
449
        mov     ecx, [crosslist+ecx*4]
449
        mov     ecx, [crosslist+ecx*4]
450
        mov     [ebx + device.name], ecx
450
        mov     [ebx + device.name], ecx
451
 
451
 
452
        DEBUGF  1, "Chip version: %s\n", ecx
452
        DEBUGF  1, "Chip version: %s\n", ecx
453
 
453
 
454
; wake up the chip
454
; wake up the chip
455
        set_io  [ebx + device.io_addr], 0
455
        set_io  [ebx + device.io_addr], 0
456
        set_io  [ebx + device.io_addr], REG_HLTCLK
456
        set_io  [ebx + device.io_addr], REG_HLTCLK
457
        mov     al, 'R'         ; run the clock
457
        mov     al, 'R'         ; run the clock
458
        out     dx, al
458
        out     dx, al
459
 
459
 
460
; unlock config and BMCR registers
460
; unlock config and BMCR registers
461
        set_io  [ebx + device.io_addr], REG_9346CR
461
        set_io  [ebx + device.io_addr], REG_9346CR
462
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
462
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
463
        out     dx, al
463
        out     dx, al
464
 
464
 
465
; enable power management
465
; enable power management
466
        set_io  [ebx + device.io_addr], REG_CONFIG1
466
        set_io  [ebx + device.io_addr], REG_CONFIG1
467
        in      al, dx
467
        in      al, dx
468
        cmp     [ebx + device.hw_ver_id], IDX_RTL8139B
468
        cmp     [ebx + device.hw_ver_id], IDX_RTL8139B
469
        jae     .new_chip
469
        jae     .new_chip
470
; wake up older chips
470
; wake up older chips
471
        and     al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN))
471
        and     al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN))
472
        out     dx, al
472
        out     dx, al
473
        jmp     .finish_wake_up
473
        jmp     .finish_wake_up
474
 
474
 
475
; set LWAKE pin to active high (default value).
475
; set LWAKE pin to active high (default value).
476
; it is for Wake-On-LAN functionality of some motherboards.
476
; it is for Wake-On-LAN functionality of some motherboards.
477
; this signal is used to inform the motherboard to execute a wake-up process.
477
; this signal is used to inform the motherboard to execute a wake-up process.
478
; only at newer chips.
478
; only at newer chips.
479
  .new_chip:
479
  .new_chip:
480
        or      al, (1 shl BIT_PMEn)
480
        or      al, (1 shl BIT_PMEn)
481
        and     al, not (1 shl BIT_LWACT)
481
        and     al, not (1 shl BIT_LWACT)
482
        out     dx, al
482
        out     dx, al
483
 
483
 
484
        set_io  [ebx + device.io_addr], REG_CONFIG4
484
        set_io  [ebx + device.io_addr], REG_CONFIG4
485
        in      al, dx
485
        in      al, dx
486
        and     al, not (1 shl BIT_LWPTN)
486
        and     al, not (1 shl BIT_LWPTN)
487
        out     dx, al
487
        out     dx, al
488
 
488
 
489
; lock config and BMCR registers
489
; lock config and BMCR registers
490
  .finish_wake_up:
490
  .finish_wake_up:
491
        xor     al, al
491
        xor     al, al
492
        set_io  [ebx + device.io_addr], 0
492
        set_io  [ebx + device.io_addr], 0
493
        set_io  [ebx + device.io_addr], REG_9346CR
493
        set_io  [ebx + device.io_addr], REG_9346CR
494
        out     dx, al
494
        out     dx, al
495
        DEBUGF  1, "probing done!\n"
495
        DEBUGF  1, "probing done!\n"
496
 
496
 
497
        xor     eax, eax
497
        xor     eax, eax
498
 
498
 
499
        ret
499
        ret
500
 
500
 
501
 
501
 
502
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
502
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
503
;;
503
;;
504
;;   reset: Set up all registers and descriptors, clear some values
504
;;   reset: Set up all registers and descriptors, clear some values
505
;;
505
;;
506
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
506
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
507
 
507
 
508
reset:
508
reset:
509
        DEBUGF  1, "Reset\n"
509
        DEBUGF  1, "Reset\n"
510
 
510
 
511
; attach int handler
511
; attach int handler
512
        movzx   eax, [ebx + device.irq_line]
512
        movzx   eax, [ebx + device.irq_line]
513
        DEBUGF  1, "Attaching int handler to irq %x\n", eax:1
513
        DEBUGF  1, "Attaching int handler to irq %x\n", eax:1
514
        invoke  AttachIntHandler, eax, int_handler, ebx
514
        invoke  AttachIntHandler, eax, int_handler, ebx
515
        test    eax, eax
515
        test    eax, eax
516
        jnz     @f
516
        jnz     @f
517
        DEBUGF  2, "Could not attach int handler!\n"
517
        DEBUGF  2, "Could not attach int handler!\n"
518
        or      eax, -1
518
        or      eax, -1
519
        ret
519
        ret
520
       @@:
520
       @@:
521
 
521
 
522
; reset chip
522
; reset chip
523
        DEBUGF  1, "Resetting chip\n"
523
        DEBUGF  1, "Resetting chip\n"
524
        set_io  [ebx + device.io_addr], 0
524
        set_io  [ebx + device.io_addr], 0
525
        set_io  [ebx + device.io_addr], REG_COMMAND
525
        set_io  [ebx + device.io_addr], REG_COMMAND
526
        mov     al, 1 shl BIT_RST
526
        mov     al, 1 shl BIT_RST
527
        out     dx, al
527
        out     dx, al
528
        mov     cx, 1000                ; wait no longer for the reset
528
        mov     cx, 1000                ; wait no longer for the reset
529
  .wait_for_reset:
529
  .wait_for_reset:
530
        in      al, dx
530
        in      al, dx
531
        test    al, 1 shl BIT_RST
531
        test    al, 1 shl BIT_RST
532
        jz      .reset_completed        ; RST remains 1 during reset
532
        jz      .reset_completed        ; RST remains 1 during reset
533
        dec     cx
533
        dec     cx
534
        jns     .wait_for_reset
534
        jns     .wait_for_reset
535
        DEBUGF  2, "Reset timeout!\n"
535
        DEBUGF  2, "Reset timeout!\n"
536
  .reset_completed:
536
  .reset_completed:
537
 
537
 
538
; Read MAC address
538
; Read MAC address
539
        call    read_mac
539
        call    read_mac
540
 
540
 
541
; unlock config and BMCR registers
541
; unlock config and BMCR registers
542
        set_io  [ebx + device.io_addr], 0
542
        set_io  [ebx + device.io_addr], 0
543
        set_io  [ebx + device.io_addr], REG_9346CR
543
        set_io  [ebx + device.io_addr], REG_9346CR
544
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
544
        mov     al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
545
        out     dx, al
545
        out     dx, al
546
 
546
 
547
; initialize multicast registers (no filtering)
547
; initialize multicast registers (no filtering)
548
        mov     eax, 0xffffffff
548
        mov     eax, 0xffffffff
549
        set_io  [ebx + device.io_addr], REG_MAR0
549
        set_io  [ebx + device.io_addr], REG_MAR0
550
        out     dx, eax
550
        out     dx, eax
551
        set_io  [ebx + device.io_addr], REG_MAR4
551
        set_io  [ebx + device.io_addr], REG_MAR4
552
        out     dx, eax
552
        out     dx, eax
553
 
553
 
554
; enable Rx/Tx
554
; enable Rx/Tx
555
        mov     al, (1 shl BIT_RE) or (1 shl BIT_TE)
555
        mov     al, (1 shl BIT_RE) or (1 shl BIT_TE)
556
        set_io  [ebx + device.io_addr], REG_COMMAND
556
        set_io  [ebx + device.io_addr], REG_COMMAND
557
        out     dx, al
557
        out     dx, al
558
 
558
 
559
; Rxbuffer size, unlimited dma burst, no wrapping, no rx threshold
559
; Rxbuffer size, unlimited dma burst, no wrapping, no rx threshold
560
; accept broadcast packets, accept physical match packets
560
; accept broadcast packets, accept physical match packets
561
        mov     eax, RX_CONFIG
561
        mov     eax, RX_CONFIG
562
        set_io  [ebx + device.io_addr], REG_RXCONFIG
562
        set_io  [ebx + device.io_addr], REG_RXCONFIG
563
        out     dx, eax
563
        out     dx, eax
564
 
564
 
565
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
565
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
566
        mov     eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0
566
        mov     eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0
567
        set_io  [ebx + device.io_addr], REG_TXCONFIG
567
        set_io  [ebx + device.io_addr], REG_TXCONFIG
568
        out     dx, eax
568
        out     dx, eax
569
 
569
 
570
; enable auto negotiation
570
; enable auto negotiation
571
        set_io  [ebx + device.io_addr], REG_BMCR
571
        set_io  [ebx + device.io_addr], REG_BMCR
572
        in      ax, dx
572
        in      ax, dx
573
        or      ax, (1 shl BIT_ANE)
573
        or      ax, (1 shl BIT_ANE)
574
        out     dx, ax
574
        out     dx, ax
575
 
575
 
576
; set auto negotiation advertisement
576
; set auto negotiation advertisement
577
        set_io  [ebx + device.io_addr], REG_ANAR
577
        set_io  [ebx + device.io_addr], REG_ANAR
578
        in      ax, dx
578
        in      ax, dx
579
        or      ax, (1 shl BIT_SELECTOR) or (1 shl BIT_10) or (1 shl BIT_10FD) or (1 shl BIT_TX) or (1 shl BIT_TXFD)
579
        or      ax, (1 shl BIT_SELECTOR) or (1 shl BIT_10) or (1 shl BIT_10FD) or (1 shl BIT_TX) or (1 shl BIT_TXFD)
580
        out     dx, ax
580
        out     dx, ax
581
 
581
 
582
; lock config and BMCR registers
582
; lock config and BMCR registers
583
        xor     eax, eax
583
        xor     eax, eax
584
        set_io  [ebx + device.io_addr], REG_9346CR
584
        set_io  [ebx + device.io_addr], REG_9346CR
585
        out     dx, al
585
        out     dx, al
586
 
586
 
587
; init RX/TX pointers
587
; init RX/TX pointers
588
        mov     [ebx + device.rx_data_offset], eax
588
        mov     [ebx + device.rx_data_offset], eax
589
        mov     [ebx + device.curr_tx_desc], al
589
        mov     [ebx + device.curr_tx_desc], al
590
;        set_io  [ebx + device.io_addr], REG_CAPR
590
;        set_io  [ebx + device.io_addr], REG_CAPR
591
;        out     dx, ax
591
;        out     dx, ax
592
 
592
 
593
; clear packet/byte counters
593
; clear packet/byte counters
594
        lea     edi, [ebx + device.bytes_tx]
594
        lea     edi, [ebx + device.bytes_tx]
595
        mov     ecx, 6
595
        mov     ecx, 6
596
        rep     stosd
596
        rep     stosd
597
 
597
 
598
; clear missing packet counter
598
; clear missing packet counter
599
        set_io  [ebx + device.io_addr], REG_MPC
599
        set_io  [ebx + device.io_addr], REG_MPC
600
        out     dx, eax
600
        out     dx, eax
601
 
601
 
602
; set RxBuffer address, init RX buffer offset
602
; set RxBuffer address, init RX buffer offset
603
        mov     eax, [ebx + device.rx_buffer]
603
        mov     eax, [ebx + device.rx_buffer]
604
        mov     dword[eax], 0                   ; clear receive flags for first packet (really needed??)
604
        mov     dword[eax], 0                   ; clear receive flags for first packet (really needed??)
605
        DEBUGF  1, "RX buffer virtual addr=0x%x\n", eax
605
        DEBUGF  1, "RX buffer virtual addr=0x%x\n", eax
606
        invoke  GetPhysAddr
606
        invoke  GetPhysAddr
607
        DEBUGF  1, "RX buffer physical addr=0x%x\n", eax
607
        DEBUGF  1, "RX buffer physical addr=0x%x\n", eax
608
        set_io  [ebx + device.io_addr], REG_RBSTART
608
        set_io  [ebx + device.io_addr], REG_RBSTART
609
        out     dx, eax
609
        out     dx, eax
610
 
610
 
611
; enable interrupts
611
; enable interrupts
612
        set_io  [ebx + device.io_addr], 0
612
        set_io  [ebx + device.io_addr], 0
613
        set_io  [ebx + device.io_addr], REG_IMR
613
        set_io  [ebx + device.io_addr], REG_IMR
614
        mov     ax, INTERRUPT_MASK
614
        mov     ax, INTERRUPT_MASK
615
        out     dx, ax
615
        out     dx, ax
616
 
616
 
617
; Set the mtu, kernel will be able to send now
617
; Set the mtu, kernel will be able to send now
618
        mov     [ebx + device.mtu], 1514
618
        mov     [ebx + device.mtu], 1514
619
 
619
 
620
        call    cable
620
        call    cable
621
 
621
 
622
; Indicate that we have successfully reset the card
622
; Indicate that we have successfully reset the card
623
        xor     eax, eax
623
        xor     eax, eax
624
        ret
624
        ret
625
 
625
 
626
 
626
 
627
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
627
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
628
;;                                         ;;
628
;;                                         ;;
629
;; Transmit                                ;;
629
;; Transmit                                ;;
630
;;                                         ;;
630
;;                                         ;;
631
;; In: buffer pointer in [esp+4]           ;;
631
;; In: buffer pointer in [esp+4]           ;;
632
;;     size of buffer in [esp+8]           ;;
632
;;     size of buffer in [esp+8]           ;;
633
;;     pointer to device structure in ebx  ;;
633
;;     pointer to device structure in ebx  ;;
634
;;                                         ;;
634
;;                                         ;;
635
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
635
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
636
 
636
 
637
proc transmit stdcall bufferptr, buffersize
637
proc transmit stdcall bufferptr, buffersize
638
 
638
 
639
        pushf
639
        pushf
640
        cli
640
        cli
641
 
641
 
642
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
642
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
643
        mov     eax, [bufferptr]
643
        mov     eax, [bufferptr]
644
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
644
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
645
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
645
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
646
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
646
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
647
        [eax+13]:2,[eax+12]:2
647
        [eax+13]:2,[eax+12]:2
648
 
648
 
649
        cmp     [buffersize], 1514
649
        cmp     [buffersize], 1514
650
        ja      .fail
650
        ja      .fail
651
        cmp     [buffersize], 60
651
        cmp     [buffersize], 60
652
        jb      .fail
652
        jb      .fail
653
 
653
 
654
; check if we own the current discriptor
654
; check if we own the current discriptor
655
        set_io  [ebx + device.io_addr], 0
655
        set_io  [ebx + device.io_addr], 0
656
        set_io  [ebx + device.io_addr], REG_TSD0
656
        set_io  [ebx + device.io_addr], REG_TSD0
657
        movzx   ecx, [ebx + device.curr_tx_desc]
657
        movzx   ecx, [ebx + device.curr_tx_desc]
658
        shl     ecx, 2
658
        shl     ecx, 2
659
        add     edx, ecx
659
        add     edx, ecx
660
        in      eax, dx
660
        in      eax, dx
661
        test    eax, (1 shl BIT_OWN)
661
        test    eax, (1 shl BIT_OWN)
662
        jz      .wait_to_send
662
        jz      .wait_to_send
663
 
663
 
664
  .send_packet:
664
  .send_packet:
665
; get next descriptor
665
; get next descriptor
666
        inc     [ebx + device.curr_tx_desc]
666
        inc     [ebx + device.curr_tx_desc]
667
        and     [ebx + device.curr_tx_desc], NUM_TX_DESC-1
667
        and     [ebx + device.curr_tx_desc], NUM_TX_DESC-1
668
 
668
 
669
; Update stats
669
; Update stats
670
        inc     [ebx + device.packets_tx]
670
        inc     [ebx + device.packets_tx]
671
        mov     eax, [buffersize]
671
        mov     eax, [buffersize]
672
        add     dword [ebx + device.bytes_tx], eax
672
        add     dword [ebx + device.bytes_tx], eax
673
        adc     dword [ebx + device.bytes_tx+4], 0
673
        adc     dword [ebx + device.bytes_tx+4], 0
674
 
674
 
675
; Set the buffer address
675
; Set the buffer address
676
        set_io  [ebx + device.io_addr], REG_TSAD0
676
        set_io  [ebx + device.io_addr], REG_TSAD0
677
        mov     eax, [bufferptr]
677
        mov     eax, [bufferptr]
678
        mov     [ebx + device.TX_DESC+ecx], eax
678
        mov     [ebx + device.TX_DESC+ecx], eax
679
        invoke  GetPhysAddr
679
        invoke  GetPhysAddr
680
        out     dx, eax
680
        out     dx, eax
681
 
681
 
682
; And the size of the buffer
682
; And the size of the buffer
683
        set_io  [ebx + device.io_addr], REG_TSD0
683
        set_io  [ebx + device.io_addr], REG_TSD0
684
        mov     eax, [buffersize]
684
        mov     eax, [buffersize]
685
        or      eax, (ERTXTH shl BIT_ERTXTH)    ; Early threshold
685
        or      eax, (ERTXTH shl BIT_ERTXTH)    ; Early threshold
686
        out     dx, eax
686
        out     dx, eax
687
 
687
 
688
        DEBUGF  1, "Packet Sent!\n"
688
        DEBUGF  1, "Packet Sent!\n"
689
        popf
689
        popf
690
        xor     eax, eax
690
        xor     eax, eax
691
        ret
691
        ret
692
 
692
 
693
  .wait_to_send:
693
  .wait_to_send:
694
        DEBUGF  1, "Waiting for timeout\n"
694
        DEBUGF  1, "Waiting for timeout\n"
695
 
695
 
696
        push    edx
696
        push    edx
697
        mov     esi, 30
697
        mov     esi, 30
698
        invoke  Sleep
698
        invoke  Sleep
699
        pop     edx
699
        pop     edx
700
 
700
 
701
        in      ax, dx
701
        in      ax, dx
702
        test    ax, (1 shl BIT_OWN)
702
        test    ax, (1 shl BIT_OWN)
703
        jnz     .send_packet
703
        jnz     .send_packet
704
 
704
 
705
        pusha
705
        pusha
706
        call    reset                            ; if chip hung, reset it
706
        call    reset                            ; if chip hung, reset it
707
        popa
707
        popa
708
 
708
 
709
        jmp     .send_packet
709
        jmp     .send_packet
710
 
710
 
711
  .fail:
711
  .fail:
712
        DEBUGF  2, "transmit failed!\n"
712
        DEBUGF  2, "transmit failed!\n"
713
        invoke  KernelFree, [bufferptr]
713
        invoke  KernelFree, [bufferptr]
714
        popf
714
        popf
715
        or      eax, -1
715
        or      eax, -1
716
        ret
716
        ret
717
 
717
 
718
endp
718
endp
719
 
719
 
720
 
720
 
721
 
721
 
722
 
722
 
723
 
723
 
724
;;;;;;;;;;;;;;;;;;;;;;;
724
;;;;;;;;;;;;;;;;;;;;;;;
725
;;                   ;;
725
;;                   ;;
726
;; Interrupt handler ;;
726
;; Interrupt handler ;;
727
;;                   ;;
727
;;                   ;;
728
;;;;;;;;;;;;;;;;;;;;;;;
728
;;;;;;;;;;;;;;;;;;;;;;;
729
 
729
 
730
align 4
730
align 4
731
int_handler:
731
int_handler:
732
 
732
 
733
        push    ebx esi edi
733
        push    ebx esi edi
734
 
734
 
735
        DEBUGF  1, "INT\n"
735
        DEBUGF  1, "INT\n"
736
 
736
 
737
; find pointer of device wich made IRQ occur
737
; find pointer of device wich made IRQ occur
738
        mov     ecx, [devices]
738
        mov     ecx, [devices]
739
        test    ecx, ecx
739
        test    ecx, ecx
740
        jz      .nothing
740
        jz      .nothing
741
        mov     esi, device_list
741
        mov     esi, device_list
742
  .nextdevice:
742
  .nextdevice:
743
        mov     ebx, [esi]
743
        mov     ebx, [esi]
744
 
744
 
745
        set_io  [ebx + device.io_addr], 0
745
        set_io  [ebx + device.io_addr], 0
746
        set_io  [ebx + device.io_addr], REG_ISR
746
        set_io  [ebx + device.io_addr], REG_ISR
747
        in      ax, dx                          ; Get interrupt status
747
        in      ax, dx                          ; Get interrupt status
748
        out     dx, ax                          ; send it back to ACK
748
        out     dx, ax                          ; send it back to ACK
749
        test    ax, ax
749
        test    ax, ax
750
        jnz     .got_it
750
        jnz     .got_it
751
  .continue:
751
  .continue:
752
        add     esi, 4
752
        add     esi, 4
753
        dec     ecx
753
        dec     ecx
754
        jnz     .nextdevice
754
        jnz     .nextdevice
755
  .nothing:
755
  .nothing:
756
        pop     edi esi ebx
756
        pop     edi esi ebx
757
        xor     eax, eax
757
        xor     eax, eax
758
 
758
 
759
        ret                                     ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
759
        ret                                     ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
760
 
760
 
761
  .got_it:
761
  .got_it:
762
 
762
 
763
        DEBUGF  1, "Device: %x Status: %x\n", ebx, ax
763
        DEBUGF  1, "Device: %x Status: %x\n", ebx, ax
764
 
764
 
765
;----------------------------------------------------
765
;----------------------------------------------------
766
; Received packet ok?
766
; Received packet ok?
767
 
767
 
768
        test    ax, ISR_ROK
768
        test    ax, ISR_ROK
769
        jz      @f
769
        jz      @f
770
        push    ax
770
        push    ax
771
 
771
 
772
  .receive:
772
  .receive:
773
        set_io  [ebx + device.io_addr], 0
773
        set_io  [ebx + device.io_addr], 0
774
        set_io  [ebx + device.io_addr], REG_COMMAND
774
        set_io  [ebx + device.io_addr], REG_COMMAND
775
        in      al, dx
775
        in      al, dx
776
        test    al, BUFE                        ; test if RX buffer is empty
776
        test    al, BUFE                        ; test if RX buffer is empty
777
        jnz     .finish
777
        jnz     .finish
778
 
778
 
779
        DEBUGF  1, "RX:\n"
779
        DEBUGF  1, "RX:\n"
780
 
780
 
781
        mov     eax, [ebx + device.rx_buffer]
781
        mov     eax, [ebx + device.rx_buffer]
782
        add     eax, [ebx + device.rx_data_offset]
782
        add     eax, [ebx + device.rx_data_offset]
783
        test    byte [eax], (1 shl BIT_ROK)     ; check if packet is ok
783
        test    byte [eax], (1 shl BIT_ROK)     ; check if packet is ok
784
        jz      .reset_rx
784
        jz      .reset_rx
785
 
785
 
786
; packet is ok, copy it
786
; packet is ok, copy it
787
        movzx   ecx, word [eax+2]               ; packet length
787
        movzx   ecx, word [eax+2]               ; packet length
788
        sub     cx, 4                           ; don't copy CRC
788
        sub     cx, 4                           ; don't copy CRC
789
 
789
 
790
; Update stats
790
; Update stats
791
        add     dword [ebx + device.bytes_rx], ecx
791
        add     dword [ebx + device.bytes_rx], ecx
792
        adc     dword [ebx + device.bytes_rx + 4], 0
792
        adc     dword [ebx + device.bytes_rx + 4], 0
793
        inc     [ebx + device.packets_rx]
793
        inc     [ebx + device.packets_rx]
794
 
794
 
795
        DEBUGF  1, "Received %u bytes\n", ecx
795
        DEBUGF  1, "Received %u bytes\n", ecx
796
 
796
 
797
        push    ebx eax ecx
797
        push    ebx eax ecx
798
        invoke  KernelAlloc, ecx                ; Allocate a buffer to put packet into
798
        invoke  KernelAlloc, ecx                ; Allocate a buffer to put packet into
799
        pop     ecx
799
        pop     ecx
800
        test    eax, eax                        ; Test if we allocated succesfully
800
        test    eax, eax                        ; Test if we allocated succesfully
801
        jz      .abort
801
        jz      .abort
802
 
802
 
803
        mov     edi, eax                        ; Where we will copy too
803
        mov     edi, eax                        ; Where we will copy too
804
 
804
 
805
        mov     esi, [esp]                      ; The buffer we will copy from
805
        mov     esi, [esp]                      ; The buffer we will copy from
806
        add     esi, 4                          ; Dont copy CRC
806
        add     esi, 4                          ; Dont copy CRC
807
 
807
 
808
        push    dword .abort                    ; Kernel will return to this address after EthReceiver
808
        push    dword .abort                    ; Kernel will return to this address after EthReceiver
809
        push    ecx edi                         ; Save buffer pointer and size, to pass to kernel
809
        push    ecx edi                         ; Save buffer pointer and size, to pass to kernel
810
 
810
 
811
  .copy:
811
  .copy:
812
        shr     ecx, 1
812
        shr     ecx, 1
813
        jnc     .nb
813
        jnc     .nb
814
        movsb
814
        movsb
815
  .nb:
815
  .nb:
816
        shr     ecx, 1
816
        shr     ecx, 1
817
        jnc     .nw
817
        jnc     .nw
818
        movsw
818
        movsw
819
  .nw:
819
  .nw:
820
        jz      .nd
820
        jz      .nd
821
        rep     movsd
821
        rep     movsd
822
  .nd:
822
  .nd:
823
 
823
 
824
        jmp     [Eth_input]                     ; Send it to kernel
824
        jmp     [Eth_input]                     ; Send it to kernel
825
 
825
 
826
  .abort:
826
  .abort:
827
        pop     eax ebx
827
        pop     eax ebx
828
                                                ; update eth_data_start_offset
828
                                                ; update eth_data_start_offset
829
        movzx   eax, word [eax+2]               ; packet length
829
        movzx   eax, word [eax+2]               ; packet length
830
        add     eax, [ebx + device.rx_data_offset]
830
        add     eax, [ebx + device.rx_data_offset]
831
        add     eax, 4+3                        ; packet header is 4 bytes long + dword alignment
831
        add     eax, 4+3                        ; packet header is 4 bytes long + dword alignment
832
        and     eax, not 3                      ; dword alignment
832
        and     eax, not 3                      ; dword alignment
833
 
833
 
834
        cmp     eax, RX_BUFFER_SIZE
834
        cmp     eax, RX_BUFFER_SIZE
835
        jb      .no_wrap
835
        jb      .no_wrap
836
        DEBUGF  1, "Wrapping\n"
836
        DEBUGF  1, "Wrapping\n"
837
        sub     eax, RX_BUFFER_SIZE
837
        sub     eax, RX_BUFFER_SIZE
838
  .no_wrap:
838
  .no_wrap:
839
        mov     [ebx + device.rx_data_offset], eax
839
        mov     [ebx + device.rx_data_offset], eax
840
        DEBUGF  1, "New RX ptr: %d\n", eax
840
        DEBUGF  1, "New RX ptr: %d\n", eax
841
 
841
 
842
        set_io  [ebx + device.io_addr], 0
842
        set_io  [ebx + device.io_addr], 0
843
        set_io  [ebx + device.io_addr], REG_CAPR                        ; update 'Current Address of Packet Read register'
843
        set_io  [ebx + device.io_addr], REG_CAPR                        ; update 'Current Address of Packet Read register'
844
        sub     eax, 0x10                       ; value 0x10 is a constant for CAPR
844
        sub     eax, 0x10                       ; value 0x10 is a constant for CAPR
845
        out     dx, ax
845
        out     dx, ax
846
 
846
 
847
        jmp     .receive                        ; check for multiple packets
847
        jmp     .receive                        ; check for multiple packets
848
 
848
 
849
  .reset_rx:
849
  .reset_rx:
850
        test    byte [eax], (1 shl BIT_CRC)
850
        test    byte [eax], (1 shl BIT_CRC)
851
        jz      .no_crc_error
851
        jz      .no_crc_error
852
        DEBUGF  2, "RX: CRC error!\n"
852
        DEBUGF  2, "RX: CRC error!\n"
853
 
853
 
854
  .no_crc_error:
854
  .no_crc_error:
855
        test    byte [eax], (1 shl BIT_FAE)
855
        test    byte [eax], (1 shl BIT_FAE)
856
        jz      .no_fae_error
856
        jz      .no_fae_error
857
        DEBUGF  2, "RX: Frame alignment error!\n"
857
        DEBUGF  2, "RX: Frame alignment error!\n"
858
 
858
 
859
  .no_fae_error:
859
  .no_fae_error:
860
        DEBUGF  1, "Reset RX\n"
860
        DEBUGF  1, "Reset RX\n"
861
        in      al, dx                          ; read command register
861
        in      al, dx                          ; read command register
862
        push    ax
862
        push    ax
863
        and     al, not (1 shl BIT_RE)          ; Clear the RE bit
863
        and     al, not (1 shl BIT_RE)          ; Clear the RE bit
864
        out     dx, al
864
        out     dx, al
865
        pop     ax
865
        pop     ax
866
        out     dx, al                          ; write original command back
866
        out     dx, al                          ; write original command back
867
 
867
 
868
        add     edx, REG_RXCONFIG - REG_COMMAND         ; Restore RX configuration
868
        add     edx, REG_RXCONFIG - REG_COMMAND         ; Restore RX configuration
869
        mov     ax, RX_CONFIG
869
        mov     ax, RX_CONFIG
870
        out     dx, ax
870
        out     dx, ax
871
 
871
 
872
  .finish:
872
  .finish:
873
        pop     ax
873
        pop     ax
874
 
874
 
875
;----------------------------------------------------
875
;----------------------------------------------------
876
; Transmit ok / Transmit error
876
; Transmit ok / Transmit error
877
  @@:
877
  @@:
878
        test    ax, ISR_TOK + ISR_TER
878
        test    ax, ISR_TOK + ISR_TER
879
        jz      @f
879
        jz      @f
880
 
880
 
881
        DEBUGF  1, "Transmit done!\n"
881
        DEBUGF  1, "Transmit done!\n"
882
 
882
 
883
        push    ax
883
        push    ax
884
        mov     ecx, (NUM_TX_DESC-1)*4
884
        mov     ecx, (NUM_TX_DESC-1)*4
885
  .txdescloop:
885
  .txdescloop:
886
        set_io  [ebx + device.io_addr], 0
886
        set_io  [ebx + device.io_addr], 0
887
        set_io  [ebx + device.io_addr], REG_TSD0
887
        set_io  [ebx + device.io_addr], REG_TSD0
888
        add     edx, ecx
888
        add     edx, ecx
889
        in      eax, dx
889
        in      eax, dx
890
 
890
 
891
        test    eax, TSR_OWN                    ; DMA operation completed
891
        test    eax, TSR_OWN                    ; DMA operation completed
892
        jz      .notthisone
892
        jz      .notthisone
893
 
893
 
894
        cmp     [ebx + device.TX_DESC+ecx], 0
894
        cmp     [ebx + device.TX_DESC+ecx], 0
895
        je      .notthisone
895
        je      .notthisone
896
 
896
 
897
        DEBUGF  1, "TSD: 0x%x\n", eax
897
        DEBUGF  1, "TSD: 0x%x\n", eax
898
 
898
 
899
        test    eax, TSR_TUN
899
        test    eax, TSR_TUN
900
        jz      .no_bun
900
        jz      .no_bun
901
        DEBUGF  2, "TX: FIFO Buffer underrun!\n"
901
        DEBUGF  2, "TX: FIFO Buffer underrun!\n"
902
 
902
 
903
  .no_bun:
903
  .no_bun:
904
        test    eax, TSR_OWC
904
        test    eax, TSR_OWC
905
        jz      .no_owc
905
        jz      .no_owc
906
        DEBUGF  2, "TX: OWC!\n"
906
        DEBUGF  2, "TX: OWC!\n"
907
 
907
 
908
  .no_owc:
908
  .no_owc:
909
        test    eax, TSR_TABT
909
        test    eax, TSR_TABT
910
        jz      .no_tabt
910
        jz      .no_tabt
911
        DEBUGF  2, "TX: TABT!\n"
911
        DEBUGF  2, "TX: TABT!\n"
912
 
912
 
913
  .no_tabt:
913
  .no_tabt:
914
        test    eax, TSR_CRS
914
        test    eax, TSR_CRS
915
        jz      .no_csl
915
        jz      .no_csl
916
        DEBUGF  2, "TX: Carrier Sense Lost!\n"
916
        DEBUGF  2, "TX: Carrier Sense Lost!\n"
917
 
917
 
918
  .no_csl:
918
  .no_csl:
919
        test    eax, TSR_TOK
919
        test    eax, TSR_TOK
920
        jz      .no_tok
920
        jz      .no_tok
921
        DEBUGF  1, "TX: Transmit OK!\n"
921
        DEBUGF  1, "TX: Transmit OK!\n"
922
 
922
 
923
  .no_tok:
923
  .no_tok:
924
        DEBUGF  1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8
924
        DEBUGF  1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8
925
        push    ecx ebx
925
        push    ecx ebx
926
        invoke  KernelFree, [ebx + device.TX_DESC+ecx]
926
        invoke  KernelFree, [ebx + device.TX_DESC+ecx]
927
        pop     ebx ecx
927
        pop     ebx ecx
928
        mov     [ebx + device.TX_DESC+ecx], 0
928
        mov     [ebx + device.TX_DESC+ecx], 0
929
 
929
 
930
  .notthisone:
930
  .notthisone:
931
        sub     ecx, 4
931
        sub     ecx, 4
932
        jae     .txdescloop
932
        jae     .txdescloop
933
        pop     ax
933
        pop     ax
934
 
934
 
935
;----------------------------------------------------
935
;----------------------------------------------------
936
; Rx buffer overflow ?
936
; Rx buffer overflow ?
937
  @@:
937
  @@:
938
        test    ax, ISR_RXOVW
938
        test    ax, ISR_RXOVW
939
        jz      @f
939
        jz      @f
940
 
940
 
941
        push    ax
941
        push    ax
942
        DEBUGF  2, "RX:buffer overflow!\n"
942
        DEBUGF  2, "RX:buffer overflow!\n"
943
 
943
 
944
        set_io  [ebx + device.io_addr], 0
944
        set_io  [ebx + device.io_addr], 0
945
        set_io  [ebx + device.io_addr], REG_ISR
945
        set_io  [ebx + device.io_addr], REG_ISR
946
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
946
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
947
        out     dx, ax
947
        out     dx, ax
948
        pop     ax
948
        pop     ax
949
 
949
 
950
;----------------------------------------------------
950
;----------------------------------------------------
951
; Packet underrun?
951
; Packet underrun?
952
  @@:
952
  @@:
953
        test    ax, ISR_PUN
953
        test    ax, ISR_PUN
954
        jz      @f
954
        jz      @f
955
 
955
 
956
        DEBUGF  1, "Packet underrun or link changed!\n"
956
        DEBUGF  1, "Packet underrun or link changed!\n"
957
 
957
 
958
        call    cable
958
        call    cable
959
 
959
 
960
;----------------------------------------------------
960
;----------------------------------------------------
961
; Receive FIFO overflow ?
961
; Receive FIFO overflow ?
962
  @@:
962
  @@:
963
        test    ax, ISR_FIFOOVW
963
        test    ax, ISR_FIFOOVW
964
        jz      @f
964
        jz      @f
965
 
965
 
966
        push    ax
966
        push    ax
967
        DEBUGF  2, "RX fifo overflow!\n"
967
        DEBUGF  2, "RX fifo overflow!\n"
968
 
968
 
969
        set_io  [ebx + device.io_addr], 0
969
        set_io  [ebx + device.io_addr], 0
970
        set_io  [ebx + device.io_addr], REG_ISR
970
        set_io  [ebx + device.io_addr], REG_ISR
971
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
971
        mov     ax, ISR_FIFOOVW or ISR_RXOVW
972
        out     dx, ax
972
        out     dx, ax
973
        pop     ax
973
        pop     ax
974
 
974
 
975
;----------------------------------------------------
975
;----------------------------------------------------
976
; cable length changed ?
976
; cable length changed ?
977
  @@:
977
  @@:
978
        test    ax, ISR_LENCHG
978
        test    ax, ISR_LENCHG
979
        jz      .fail
979
        jz      .fail
980
 
980
 
981
        DEBUGF  2, "Cable length changed!\n"
981
        DEBUGF  2, "Cable length changed!\n"
982
 
982
 
983
        call    cable
983
        call    cable
984
 
984
 
985
  .fail:
985
  .fail:
986
        pop     edi esi ebx
986
        pop     edi esi ebx
987
        xor     eax, eax
987
        xor     eax, eax
988
        inc     eax
988
        inc     eax
989
 
989
 
990
        ret
990
        ret
991
 
991
 
992
 
992
 
993
 
993
 
994
 
994
 
995
;;;;;;;;;;;;;;;;;;;;;;;;;
995
;;;;;;;;;;;;;;;;;;;;;;;;;
996
;;                     ;;
996
;;                     ;;
997
;; Update Cable status ;;
997
;; Update Cable status ;;
998
;;                     ;;
998
;;                     ;;
999
;;;;;;;;;;;;;;;;;;;;;;;;;
999
;;;;;;;;;;;;;;;;;;;;;;;;;
1000
 
1000
 
1001
align 4
1001
align 4
1002
cable:
1002
cable:
1003
        DEBUGF  1, "Checking link status:\n"
1003
        DEBUGF  1, "Checking link status:\n"
1004
 
1004
 
1005
        set_io  [ebx + device.io_addr], 0
1005
        set_io  [ebx + device.io_addr], 0
1006
        set_io  [ebx + device.io_addr], REG_MSR
1006
        set_io  [ebx + device.io_addr], REG_MSR
1007
        in      al, dx
1007
        in      al, dx
1008
 
1008
 
1009
        test    al, 1 shl 2             ; 0 = link ok 1 = link fail
1009
        test    al, 1 shl 2             ; 0 = link ok 1 = link fail
1010
        jnz     .notconnected
1010
        jnz     .notconnected
1011
 
1011
 
1012
        test    al, 1 shl 3             ; 0 = 100 Mbps 1 = 10 Mbps
1012
        test    al, 1 shl 3             ; 0 = 100 Mbps 1 = 10 Mbps
1013
        jnz     .10mbps
1013
        jnz     .10mbps
1014
 
1014
 
1015
  .100mbps:
1015
  .100mbps:
1016
        mov     [ebx + device.state], ETH_LINK_100M
1016
        mov     [ebx + device.state], ETH_LINK_100M
1017
        invoke  NetLinkChanged
1017
        invoke  NetLinkChanged
1018
        DEBUGF  2, "link changed to 100 mbit\n"
1018
        DEBUGF  2, "link changed to 100 mbit\n"
1019
 
1019
 
1020
        ret
1020
        ret
1021
 
1021
 
1022
  .10mbps:
1022
  .10mbps:
1023
        mov     [ebx + device.state], ETH_LINK_10M
1023
        mov     [ebx + device.state], ETH_LINK_10M
1024
        invoke  NetLinkChanged
1024
        invoke  NetLinkChanged
1025
        DEBUGF  2, "link changed to 10 mbit\n"
1025
        DEBUGF  2, "link changed to 10 mbit\n"
1026
 
1026
 
1027
        ret
1027
        ret
1028
 
1028
 
1029
  .notconnected:
1029
  .notconnected:
1030
        mov     [ebx + device.state], ETH_LINK_DOWN
1030
        mov     [ebx + device.state], ETH_LINK_DOWN
1031
        invoke  NetLinkChanged
1031
        invoke  NetLinkChanged
1032
        DEBUGF  2, "no link\n"
1032
        DEBUGF  2, "no link\n"
1033
 
1033
 
1034
        ret
1034
        ret
1035
 
1035
 
1036
 
1036
 
1037
 
1037
 
1038
;;;;;;;;;;;;;;;;;;;;;;;
1038
;;;;;;;;;;;;;;;;;;;;;;;
1039
;;                   ;;
1039
;;                   ;;
1040
;; Write MAC address ;;
1040
;; Write MAC address ;;
1041
;;                   ;;
1041
;;                   ;;
1042
;;;;;;;;;;;;;;;;;;;;;;;
1042
;;;;;;;;;;;;;;;;;;;;;;;
1043
 
1043
 
1044
align 4
1044
align 4
1045
write_mac:      ; in: mac pushed onto stack (as 3 words)
1045
write_mac:      ; in: mac pushed onto stack (as 3 words)
1046
 
1046
 
1047
        DEBUGF  1, "Writing MAC\n"
1047
        DEBUGF  1, "Writing MAC\n"
1048
 
1048
 
1049
; disable all in command registers
1049
; disable all in command registers
1050
        set_io  [ebx + device.io_addr], 0
1050
        set_io  [ebx + device.io_addr], 0
1051
        set_io  [ebx + device.io_addr], REG_9346CR
1051
        set_io  [ebx + device.io_addr], REG_9346CR
1052
        xor     eax, eax
1052
        xor     eax, eax
1053
        out     dx, al
1053
        out     dx, al
1054
 
1054
 
1055
        set_io  [ebx + device.io_addr], REG_IMR
1055
        set_io  [ebx + device.io_addr], REG_IMR
1056
        xor     eax, eax
1056
        xor     eax, eax
1057
        out     dx, ax
1057
        out     dx, ax
1058
 
1058
 
1059
        set_io  [ebx + device.io_addr], REG_ISR
1059
        set_io  [ebx + device.io_addr], REG_ISR
1060
        mov     eax, -1
1060
        mov     eax, -1
1061
        out     dx, ax
1061
        out     dx, ax
1062
 
1062
 
1063
; enable writing
1063
; enable writing
1064
        set_io  [ebx + device.io_addr], REG_9346CR
1064
        set_io  [ebx + device.io_addr], REG_9346CR
1065
        mov     eax, REG_9346CR_WE
1065
        mov     eax, REG_9346CR_WE
1066
        out     dx, al
1066
        out     dx, al
1067
 
1067
 
1068
 ; write the mac ...
1068
 ; write the mac ...
1069
        set_io  [ebx + device.io_addr], REG_IDR0
1069
        set_io  [ebx + device.io_addr], REG_IDR0
1070
        pop     eax
1070
        pop     eax
1071
        out     dx, eax
1071
        out     dx, eax
1072
 
1072
 
1073
        set_io  [ebx + device.io_addr], REG_IDR0+4
1073
        set_io  [ebx + device.io_addr], REG_IDR0+4
1074
        xor     eax, eax
1074
        xor     eax, eax
1075
        pop     ax
1075
        pop     ax
1076
        out     dx, eax
1076
        out     dx, eax
1077
 
1077
 
1078
; disable writing
1078
; disable writing
1079
        set_io  [ebx + device.io_addr], REG_9346CR
1079
        set_io  [ebx + device.io_addr], REG_9346CR
1080
        xor     eax, eax
1080
        xor     eax, eax
1081
        out     dx, al
1081
        out     dx, al
1082
 
1082
 
1083
        DEBUGF  1, "MAC write ok!\n"
1083
        DEBUGF  1, "MAC write ok!\n"
1084
 
1084
 
1085
; Notice this procedure does not ret, but continues to read_mac instead.
1085
; Notice this procedure does not ret, but continues to read_mac instead.
1086
 
1086
 
1087
 
1087
 
1088
;;;;;;;;;;;;;;;;;;;;;;
1088
;;;;;;;;;;;;;;;;;;;;;;
1089
;;                  ;;
1089
;;                  ;;
1090
;; Read MAC address ;;
1090
;; Read MAC address ;;
1091
;;                  ;;
1091
;;                  ;;
1092
;;;;;;;;;;;;;;;;;;;;;;
1092
;;;;;;;;;;;;;;;;;;;;;;
1093
 
1093
 
1094
read_mac:
1094
read_mac:
1095
        DEBUGF  1, "Reading MAC:\n"
1095
        DEBUGF  1, "Reading MAC:\n"
1096
 
1096
 
1097
        set_io  [ebx + device.io_addr], 0
1097
        set_io  [ebx + device.io_addr], 0
1098
        lea     edi, [ebx + device.mac]
1098
        lea     edi, [ebx + device.mac]
1099
        in      eax, dx
1099
        in      eax, dx
1100
        stosd
1100
        stosd
1101
        add     edx, 4
1101
        add     edx, 4
1102
        in      ax, dx
1102
        in      ax, dx
1103
        stosw
1103
        stosw
1104
 
1104
 
1105
        DEBUGF  1, "%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
1105
        DEBUGF  1, "%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
1106
 
1106
 
1107
        ret
1107
        ret
1108
 
1108
 
1109
 
1109
 
1110
; End of code
1110
; End of code
1111
 
1111
 
1112
data fixups
1112
data fixups
1113
end data
1113
end data
1114
 
1114
 
1115
include '../peimport.inc'
1115
include '../peimport.inc'
1116
 
1116
 
1117
my_service      db 'RTL8139',0                    ; max 16 chars include zero
1117
my_service      db 'RTL8139',0                    ; max 16 chars include zero
1118
 
1118
 
1119
device_1        db 'Realtek 8139',0
1119
device_1        db 'Realtek 8139',0
1120
device_2        db 'Realtek 8139A',0
1120
device_2        db 'Realtek 8139A',0
1121
device_3        db 'Realtek 8139B',0
1121
device_3        db 'Realtek 8139B',0
1122
device_4        db 'Realtek 8139C',0
1122
device_4        db 'Realtek 8139C',0
1123
device_5        db 'Realtek 8100',0
1123
device_5        db 'Realtek 8100',0
1124
device_6        db 'Realtek 8139D',0
1124
device_6        db 'Realtek 8139D',0
1125
device_7        db 'Realtek 8139CP',0
1125
device_7        db 'Realtek 8139CP',0
1126
device_8        db 'Realtek 8101',0
1126
device_8        db 'Realtek 8101',0
1127
device_unknown  db 'Unknown RTL8139 clone', 0
1127
device_unknown  db 'Unknown RTL8139 clone', 0
1128
 
1128
 
1129
crosslist:
1129
crosslist:
1130
        dd device_1
1130
        dd device_1
1131
        dd device_2
1131
        dd device_2
1132
        dd device_3
1132
        dd device_3
1133
        dd device_4
1133
        dd device_4
1134
        dd device_5
1134
        dd device_5
1135
        dd device_6
1135
        dd device_6
1136
        dd device_7
1136
        dd device_7
1137
        dd device_8
1137
        dd device_8
1138
        dd device_unknown
1138
        dd device_unknown
1139
 
1139
 
1140
hw_ver_array:                    ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
1140
hw_ver_array:                    ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
1141
        db VER_RTL8139
1141
        db VER_RTL8139
1142
        db VER_RTL8139A
1142
        db VER_RTL8139A
1143
        db VER_RTL8139B
1143
        db VER_RTL8139B
1144
        db VER_RTL8139C
1144
        db VER_RTL8139C
1145
        db VER_RTL8100
1145
        db VER_RTL8100
1146
        db VER_RTL8139D
1146
        db VER_RTL8139D
1147
        db VER_RTL8139CP
1147
        db VER_RTL8139CP
1148
        db VER_RTL8101
1148
        db VER_RTL8101
1149
        db 0
1149
        db 0
1150
 
1150
 
1151
HW_VER_ARRAY_SIZE = $-hw_ver_array
1151
HW_VER_ARRAY_SIZE = $-hw_ver_array
1152
 
1152
 
1153
include_debug_strings                           ; All data wich FDO uses will be included here
1153
include_debug_strings                           ; All data wich FDO uses will be included here
1154
 
1154
 
1155
align 4
1155
align 4
1156
devices         dd 0
1156
devices         dd 0
1157
device_list     rd MAX_DEVICES                   ; This list contains all pointers to device structures the driver is handling
1157
device_list     rd MAX_DEVICES                   ; This list contains all pointers to device structures the driver is handling