Subversion Repositories Kolibri OS

Rev

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

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