Subversion Repositories Kolibri OS

Rev

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

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