Subversion Repositories Kolibri OS

Rev

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

Rev 3545 Rev 4301
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2013. 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
;;  RTL8169 driver for KolibriOS                                   ;;
6
;;  RTL8169 driver for KolibriOS                                   ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Copyright 2007 mike.dld,                                       ;;
8
;;  Copyright 2007 mike.dld,                                       ;;
9
;;   mike.dld@gmail.com                                            ;;
9
;;   mike.dld@gmail.com                                            ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;; port to net branch by hidnplayr                                 ;;
11
;; port to net branch by hidnplayr                                 ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;  References:                                                    ;;
13
;;  References:                                                    ;;
14
;;    r8169.c - linux driver (etherboot project)                   ;;
14
;;    r8169.c - linux driver (etherboot project)                   ;;
15
;;                                                                 ;;
15
;;                                                                 ;;
16
;;          GNU GENERAL PUBLIC LICENSE                             ;;
16
;;          GNU GENERAL PUBLIC LICENSE                             ;;
17
;;             Version 2, June 1991                                ;;
17
;;             Version 2, June 1991                                ;;
18
;;                                                                 ;;
18
;;                                                                 ;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
 
20
 
21
format MS COFF
21
format MS COFF
22
 
22
 
23
        API_VERSION             = 0x01000100
23
        API_VERSION             = 0x01000100
24
        DRIVER_VERSION          = 5
24
        DRIVER_VERSION          = 5
25
 
25
 
26
        MAX_DEVICES             = 16
26
        MAX_DEVICES             = 16
27
 
27
 
28
        DEBUG                   = 1
28
        DEBUG                   = 1
29
        __DEBUG__               = 1
29
        __DEBUG__               = 1
30
        __DEBUG_LEVEL__         = 2
30
        __DEBUG_LEVEL__         = 2
31
 
31
 
32
        NUM_TX_DESC             = 4
32
        NUM_TX_DESC             = 4
33
        NUM_RX_DESC             = 4
33
        NUM_RX_DESC             = 4
34
 
34
 
35
include '../proc32.inc'
35
include '../proc32.inc'
36
include '../imports.inc'
36
include '../imports.inc'
37
include '../fdo.inc'
37
include '../fdo.inc'
38
include '../netdrv.inc'
38
include '../netdrv.inc'
39
 
39
 
40
public START
40
public START
41
public service_proc
41
public service_proc
42
public version
42
public version
43
 
43
 
44
 
44
 
45
        REG_MAC0                = 0x0 ; Ethernet hardware address
45
        REG_MAC0                = 0x0 ; Ethernet hardware address
46
        REG_MAR0                = 0x8 ; Multicast filter
46
        REG_MAR0                = 0x8 ; Multicast filter
47
        REG_TxDescStartAddr     = 0x20
47
        REG_TxDescStartAddr     = 0x20
48
        REG_TxHDescStartAddr    = 0x28
48
        REG_TxHDescStartAddr    = 0x28
49
        REG_FLASH               = 0x30
49
        REG_FLASH               = 0x30
50
        REG_ERSR                = 0x36
50
        REG_ERSR                = 0x36
51
        REG_ChipCmd             = 0x37
51
        REG_ChipCmd             = 0x37
52
        REG_TxPoll              = 0x38
52
        REG_TxPoll              = 0x38
53
        REG_IntrMask            = 0x3C
53
        REG_IntrMask            = 0x3C
54
        REG_IntrStatus          = 0x3E
54
        REG_IntrStatus          = 0x3E
55
        REG_TxConfig            = 0x40
55
        REG_TxConfig            = 0x40
56
        REG_RxConfig            = 0x44
56
        REG_RxConfig            = 0x44
57
        REG_RxMissed            = 0x4C
57
        REG_RxMissed            = 0x4C
58
        REG_Cfg9346             = 0x50
58
        REG_Cfg9346             = 0x50
59
        REG_Config0             = 0x51
59
        REG_Config0             = 0x51
60
        REG_Config1             = 0x52
60
        REG_Config1             = 0x52
61
        REG_Config2             = 0x53
61
        REG_Config2             = 0x53
62
        REG_Config3             = 0x54
62
        REG_Config3             = 0x54
63
        REG_Config4             = 0x55
63
        REG_Config4             = 0x55
64
        REG_Config5             = 0x56
64
        REG_Config5             = 0x56
65
        REG_MultiIntr           = 0x5C
65
        REG_MultiIntr           = 0x5C
66
        REG_PHYAR               = 0x60
66
        REG_PHYAR               = 0x60
67
        REG_TBICSR              = 0x64
67
        REG_TBICSR              = 0x64
68
        REG_TBI_ANAR            = 0x68
68
        REG_TBI_ANAR            = 0x68
69
        REG_TBI_LPAR            = 0x6A
69
        REG_TBI_LPAR            = 0x6A
70
        REG_PHYstatus           = 0x6C
70
        REG_PHYstatus           = 0x6C
71
        REG_RxMaxSize           = 0xDA
71
        REG_RxMaxSize           = 0xDA
72
        REG_CPlusCmd            = 0xE0
72
        REG_CPlusCmd            = 0xE0
73
        REG_RxDescStartAddr     = 0xE4
73
        REG_RxDescStartAddr     = 0xE4
74
        REG_ETThReg             = 0xEC
74
        REG_ETThReg             = 0xEC
75
        REG_FuncEvent           = 0xF0
75
        REG_FuncEvent           = 0xF0
76
        REG_FuncEventMask       = 0xF4
76
        REG_FuncEventMask       = 0xF4
77
        REG_FuncPresetState     = 0xF8
77
        REG_FuncPresetState     = 0xF8
78
        REG_FuncForceEvent      = 0xFC
78
        REG_FuncForceEvent      = 0xFC
79
 
79
 
80
        ; InterruptStatusBits
80
        ; InterruptStatusBits
81
        ISB_SYSErr              = 0x8000
81
        ISB_SYSErr              = 0x8000
82
        ISB_PCSTimeout          = 0x4000
82
        ISB_PCSTimeout          = 0x4000
83
        ISB_SWInt               = 0x0100
83
        ISB_SWInt               = 0x0100
84
        ISB_TxDescUnavail       = 0x80
84
        ISB_TxDescUnavail       = 0x80
85
        ISB_RxFIFOOver          = 0x40
85
        ISB_RxFIFOOver          = 0x40
86
        ISB_LinkChg             = 0x20
86
        ISB_LinkChg             = 0x20
87
        ISB_RxOverflow          = 0x10
87
        ISB_RxOverflow          = 0x10
88
        ISB_TxErr               = 0x08
88
        ISB_TxErr               = 0x08
89
        ISB_TxOK                = 0x04
89
        ISB_TxOK                = 0x04
90
        ISB_RxErr               = 0x02
90
        ISB_RxErr               = 0x02
91
        ISB_RxOK                = 0x01
91
        ISB_RxOK                = 0x01
92
 
92
 
93
        ; RxStatusDesc
93
        ; RxStatusDesc
94
        SD_RxRES                = 0x00200000
94
        SD_RxRES                = 0x00200000
95
        SD_RxCRC                = 0x00080000
95
        SD_RxCRC                = 0x00080000
96
        SD_RxRUNT               = 0x00100000
96
        SD_RxRUNT               = 0x00100000
97
        SD_RxRWT                = 0x00400000
97
        SD_RxRWT                = 0x00400000
98
 
98
 
99
        ; ChipCmdBits
99
        ; ChipCmdBits
100
        CMD_Reset               = 0x10
100
        CMD_Reset               = 0x10
101
        CMD_RxEnb               = 0x08
101
        CMD_RxEnb               = 0x08
102
        CMD_TxEnb               = 0x04
102
        CMD_TxEnb               = 0x04
103
        CMD_RxBufEmpty          = 0x01
103
        CMD_RxBufEmpty          = 0x01
104
 
104
 
105
        ; Cfg9346Bits
105
        ; Cfg9346Bits
106
        CFG_9346_Lock           = 0x00
106
        CFG_9346_Lock           = 0x00
107
        CFG_9346_Unlock         = 0xC0
107
        CFG_9346_Unlock         = 0xC0
108
 
108
 
109
        ; rx_mode_bits
109
        ; rx_mode_bits
110
        RXM_AcceptErr           = 0x20
110
        RXM_AcceptErr           = 0x20
111
        RXM_AcceptRunt          = 0x10
111
        RXM_AcceptRunt          = 0x10
112
        RXM_AcceptBroadcast     = 0x08
112
        RXM_AcceptBroadcast     = 0x08
113
        RXM_AcceptMulticast     = 0x04
113
        RXM_AcceptMulticast     = 0x04
114
        RXM_AcceptMyPhys        = 0x02
114
        RXM_AcceptMyPhys        = 0x02
115
        RXM_AcceptAllPhys       = 0x01
115
        RXM_AcceptAllPhys       = 0x01
116
 
116
 
117
        ; RxConfigBits
117
        ; RxConfigBits
118
        RXC_FIFOShift           = 13
118
        RXC_FIFOShift           = 13
119
        RXC_DMAShift            = 8
119
        RXC_DMAShift            = 8
120
 
120
 
121
        ; TxConfigBits
121
        ; TxConfigBits
122
        TXC_InterFrameGapShift  = 24
122
        TXC_InterFrameGapShift  = 24
123
        TXC_DMAShift            = 8    ; DMA burst value (0-7) is shift this many bits
123
        TXC_DMAShift            = 8    ; DMA burst value (0-7) is shift this many bits
124
 
124
 
125
        ; PHYstatus
125
        ; PHYstatus
126
        PHYS_TBI_Enable         = 0x80
126
        PHYS_TBI_Enable         = 0x80
127
        PHYS_TxFlowCtrl         = 0x40
127
        PHYS_TxFlowCtrl         = 0x40
128
        PHYS_RxFlowCtrl         = 0x20
128
        PHYS_RxFlowCtrl         = 0x20
129
        PHYS_1000bpsF           = 0x10
129
        PHYS_1000bpsF           = 0x10
130
        PHYS_100bps             = 0x08
130
        PHYS_100bps             = 0x08
131
        PHYS_10bps              = 0x04
131
        PHYS_10bps              = 0x04
132
        PHYS_LinkStatus         = 0x02
132
        PHYS_LinkStatus         = 0x02
133
        PHYS_FullDup            = 0x01
133
        PHYS_FullDup            = 0x01
134
 
134
 
135
        ; GIGABIT_PHY_registers
135
        ; GIGABIT_PHY_registers
136
        PHY_CTRL_REG            = 0
136
        PHY_CTRL_REG            = 0
137
        PHY_STAT_REG            = 1
137
        PHY_STAT_REG            = 1
138
        PHY_AUTO_NEGO_REG       = 4
138
        PHY_AUTO_NEGO_REG       = 4
139
        PHY_1000_CTRL_REG       = 9
139
        PHY_1000_CTRL_REG       = 9
140
 
140
 
141
        ; GIGABIT_PHY_REG_BIT
141
        ; GIGABIT_PHY_REG_BIT
142
        PHY_Restart_Auto_Nego   = 0x0200
142
        PHY_Restart_Auto_Nego   = 0x0200
143
        PHY_Enable_Auto_Nego    = 0x1000
143
        PHY_Enable_Auto_Nego    = 0x1000
144
 
144
 
145
        ; PHY_STAT_REG = 1
145
        ; PHY_STAT_REG = 1
146
        PHY_Auto_Neco_Comp      = 0x0020
146
        PHY_Auto_Neco_Comp      = 0x0020
147
 
147
 
148
        ; PHY_AUTO_NEGO_REG = 4
148
        ; PHY_AUTO_NEGO_REG = 4
149
        PHY_Cap_10_Half         = 0x0020
149
        PHY_Cap_10_Half         = 0x0020
150
        PHY_Cap_10_Full         = 0x0040
150
        PHY_Cap_10_Full         = 0x0040
151
        PHY_Cap_100_Half        = 0x0080
151
        PHY_Cap_100_Half        = 0x0080
152
        PHY_Cap_100_Full        = 0x0100
152
        PHY_Cap_100_Full        = 0x0100
153
 
153
 
154
        ; PHY_1000_CTRL_REG = 9
154
        ; PHY_1000_CTRL_REG = 9
155
        PHY_Cap_1000_Full       = 0x0200
155
        PHY_Cap_1000_Full       = 0x0200
156
        PHY_Cap_1000_Half       = 0x0100
156
        PHY_Cap_1000_Half       = 0x0100
157
 
157
 
158
        PHY_Cap_PAUSE           = 0x0400
158
        PHY_Cap_PAUSE           = 0x0400
159
        PHY_Cap_ASYM_PAUSE      = 0x0800
159
        PHY_Cap_ASYM_PAUSE      = 0x0800
160
 
160
 
161
        PHY_Cap_Null            = 0x0
161
        PHY_Cap_Null            = 0x0
162
 
162
 
163
        ; _MediaType
163
        ; _MediaType
164
        MT_10_Half              = 0x01
164
        MT_10_Half              = 0x01
165
        MT_10_Full              = 0x02
165
        MT_10_Full              = 0x02
166
        MT_100_Half             = 0x04
166
        MT_100_Half             = 0x04
167
        MT_100_Full             = 0x08
167
        MT_100_Full             = 0x08
168
        MT_1000_Full            = 0x10
168
        MT_1000_Full            = 0x10
169
 
169
 
170
        ; _TBICSRBit
170
        ; _TBICSRBit
171
        TBI_LinkOK              = 0x02000000
171
        TBI_LinkOK              = 0x02000000
172
 
172
 
173
        ; _DescStatusBit
173
        ; _DescStatusBit
174
        DSB_OWNbit              = 0x80000000
174
        DSB_OWNbit              = 0x80000000
175
        DSB_EORbit              = 0x40000000
175
        DSB_EORbit              = 0x40000000
176
        DSB_FSbit               = 0x20000000
176
        DSB_FSbit               = 0x20000000
177
        DSB_LSbit               = 0x10000000
177
        DSB_LSbit               = 0x10000000
178
 
178
 
179
        RX_BUF_SIZE             = 1536          ; Rx Buffer size
179
        RX_BUF_SIZE             = 1536          ; Rx Buffer size
180
 
180
 
181
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
181
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
182
        MAX_ETH_FRAME_SIZE      = 1536
182
        MAX_ETH_FRAME_SIZE      = 1536
183
 
183
 
184
        TX_FIFO_THRESH          = 256           ; In bytes
184
        TX_FIFO_THRESH          = 256           ; In bytes
185
 
185
 
186
        RX_FIFO_THRESH          = 7             ; 7 means NO threshold, Rx buffer level before first PCI xfer
186
        RX_FIFO_THRESH          = 7             ; 7 means NO threshold, Rx buffer level before first PCI xfer
187
        RX_DMA_BURST            = 7             ; Maximum PCI burst, '6' is 1024
187
        RX_DMA_BURST            = 7             ; Maximum PCI burst, '6' is 1024
188
        TX_DMA_BURST            = 7             ; Maximum PCI burst, '6' is 1024
188
        TX_DMA_BURST            = 7             ; Maximum PCI burst, '6' is 1024
189
        ETTh                    = 0x3F          ; 0x3F means NO threshold
189
        ETTh                    = 0x3F          ; 0x3F means NO threshold
190
 
190
 
191
        EarlyTxThld             = 0x3F          ; 0x3F means NO early transmit
191
        EarlyTxThld             = 0x3F          ; 0x3F means NO early transmit
192
        RxPacketMaxSize         = 0x0800        ; Maximum size supported is 16K-1
192
        RxPacketMaxSize         = 0x0800        ; Maximum size supported is 16K-1
193
        InterFrameGap           = 0x03          ; 3 means InterFrameGap = the shortest one
193
        InterFrameGap           = 0x03          ; 3 means InterFrameGap = the shortest one
194
 
194
 
195
        HZ                      = 1000
195
        HZ                      = 1000
196
 
196
 
197
        RTL_MIN_IO_SIZE         = 0x80
197
        RTL_MIN_IO_SIZE         = 0x80
198
        TX_TIMEOUT              = (6*HZ)
198
        TX_TIMEOUT              = (6*HZ)
199
 
199
 
200
        TIMER_EXPIRE_TIME       = 100
200
        TIMER_EXPIRE_TIME       = 100
201
 
201
 
202
        ETH_HDR_LEN             = 14
202
        ETH_HDR_LEN             = 14
203
        DEFAULT_MTU             = 1500
203
        DEFAULT_MTU             = 1500
204
        DEFAULT_RX_BUF_LEN      = 1536
204
        DEFAULT_RX_BUF_LEN      = 1536
205
 
205
 
206
 
206
 
207
;ifdef   JUMBO_FRAME_SUPPORT
207
;ifdef   JUMBO_FRAME_SUPPORT
208
;        MAX_JUMBO_FRAME_MTU     = 10000
208
;        MAX_JUMBO_FRAME_MTU     = 10000
209
;        MAX_RX_SKBDATA_SIZE     = (MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN )
209
;        MAX_RX_SKBDATA_SIZE     = (MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN )
210
;else
210
;else
211
        MAX_RX_SKBDATA_SIZE     = 1600
211
        MAX_RX_SKBDATA_SIZE     = 1600
212
;end if
212
;end if
213
 
213
 
214
        MCFG_METHOD_01          = 0x01
214
        MCFG_METHOD_01          = 0x01
215
        MCFG_METHOD_02          = 0x02
215
        MCFG_METHOD_02          = 0x02
216
        MCFG_METHOD_03          = 0x03
216
        MCFG_METHOD_03          = 0x03
217
        MCFG_METHOD_04          = 0x04
217
        MCFG_METHOD_04          = 0x04
218
        MCFG_METHOD_05          = 0x05
218
        MCFG_METHOD_05          = 0x05
219
        MCFG_METHOD_11          = 0x0b
219
        MCFG_METHOD_11          = 0x0b
220
        MCFG_METHOD_12          = 0x0c
220
        MCFG_METHOD_12          = 0x0c
221
        MCFG_METHOD_13          = 0x0d
221
        MCFG_METHOD_13          = 0x0d
222
        MCFG_METHOD_14          = 0x0e
222
        MCFG_METHOD_14          = 0x0e
223
        MCFG_METHOD_15          = 0x0f
223
        MCFG_METHOD_15          = 0x0f
224
 
224
 
225
        PCFG_METHOD_1           = 0x01          ; PHY Reg 0x03 bit0-3 == 0x0000
225
        PCFG_METHOD_1           = 0x01          ; PHY Reg 0x03 bit0-3 == 0x0000
226
        PCFG_METHOD_2           = 0x02          ; PHY Reg 0x03 bit0-3 == 0x0001
226
        PCFG_METHOD_2           = 0x02          ; PHY Reg 0x03 bit0-3 == 0x0001
227
        PCFG_METHOD_3           = 0x03          ; PHY Reg 0x03 bit0-3 == 0x0002
227
        PCFG_METHOD_3           = 0x03          ; PHY Reg 0x03 bit0-3 == 0x0002
228
 
228
 
229
virtual at 0
229
virtual at 0
230
  tx_desc:
230
  tx_desc:
231
  .status    dd ?
231
  .status    dd ?
232
  .vlan_tag  dd ?
232
  .vlan_tag  dd ?
233
  .buf_addr  dq ?
233
  .buf_addr  dq ?
234
  .size = $
234
  .size = $
235
  rb    (NUM_TX_DESC-1)*tx_desc.size
235
  rb    (NUM_TX_DESC-1)*tx_desc.size
236
  .buf_soft_addr        dd ?
236
  .buf_soft_addr        dd ?
237
end virtual
237
end virtual
238
 
238
 
239
virtual at 0
239
virtual at 0
240
  rx_desc:
240
  rx_desc:
241
  .status    dd ?
241
  .status    dd ?
242
  .vlan_tag  dd ?
242
  .vlan_tag  dd ?
243
  .buf_addr  dq ?
243
  .buf_addr  dq ?
244
  .size = $
244
  .size = $
245
  rb    (NUM_RX_DESC-1)*rx_desc.size
245
  rb    (NUM_RX_DESC-1)*rx_desc.size
246
  .buf_soft_addr        dd ?
246
  .buf_soft_addr        dd ?
247
end virtual
247
end virtual
248
 
248
 
249
virtual at ebx
249
virtual at ebx
250
 
250
 
251
        device:
251
        device:
252
 
252
 
253
        ETH_DEVICE
253
        ETH_DEVICE
254
 
254
 
255
        .io_addr        dd ?
255
        .io_addr        dd ?
256
        .pci_bus        dd ?
256
        .pci_bus        dd ?
257
        .pci_dev        dd ?
257
        .pci_dev        dd ?
258
        .irq_line       db ?
258
        .irq_line       db ?
259
 
259
 
260
        rb 256-(($ - device) and 255)              ;        align 256
260
        rb 256-(($ - device) and 255)              ;        align 256
261
        .tx_ring rb NUM_TX_DESC * tx_desc.size * 2
261
        .tx_ring rb NUM_TX_DESC * tx_desc.size * 2
262
 
262
 
263
        rb 256-(($ - device) and 255)              ;        align 256
263
        rb 256-(($ - device) and 255)              ;        align 256
264
        .rx_ring rb NUM_RX_DESC * rx_desc.size * 2
264
        .rx_ring rb NUM_RX_DESC * rx_desc.size * 2
265
 
265
 
266
        tpc:
266
        tpc:
267
        .mmio_addr      dd ? ; memory map physical address
267
        .mmio_addr      dd ? ; memory map physical address
268
        .chipset        dd ?
268
        .chipset        dd ?
269
        .pcfg           dd ?
269
        .pcfg           dd ?
270
        .mcfg           dd ?
270
        .mcfg           dd ?
271
        .cur_rx         dd ? ; Index into the Rx descriptor buffer of next Rx pkt
271
        .cur_rx         dd ? ; Index into the Rx descriptor buffer of next Rx pkt
272
        .cur_tx         dd ? ; Index into the Tx descriptor buffer of next Rx pkt
272
        .cur_tx         dd ? ; Index into the Tx descriptor buffer of next Rx pkt
273
        .TxDescArrays   dd ? ; Index of Tx Descriptor buffer
273
        .TxDescArrays   dd ? ; Index of Tx Descriptor buffer
274
        .RxDescArrays   dd ? ; Index of Rx Descriptor buffer
274
        .RxDescArrays   dd ? ; Index of Rx Descriptor buffer
275
        .TxDescArray    dd ? ; Index of 256-alignment Tx Descriptor buffer
275
        .TxDescArray    dd ? ; Index of 256-alignment Tx Descriptor buffer
276
        .RxDescArray    dd ? ; Index of 256-alignment Rx Descriptor buffer
276
        .RxDescArray    dd ? ; Index of 256-alignment Rx Descriptor buffer
277
 
277
 
278
        device_size = $ - device
278
        device_size = $ - device
279
 
279
 
280
end virtual
280
end virtual
281
 
281
 
282
        intr_mask = ISB_LinkChg or ISB_RxOverflow or ISB_RxFIFOOver or ISB_TxErr or ISB_TxOK or ISB_RxErr or ISB_RxOK
282
        intr_mask = ISB_LinkChg or ISB_RxOverflow or ISB_RxFIFOOver or ISB_TxErr or ISB_TxOK or ISB_RxErr or ISB_RxOK
283
        rx_config = (RX_FIFO_THRESH shl RXC_FIFOShift) or (RX_DMA_BURST shl RXC_DMAShift) or 0x0000000E
283
        rx_config = (RX_FIFO_THRESH shl RXC_FIFOShift) or (RX_DMA_BURST shl RXC_DMAShift) or 0x0000000E
284
 
284
 
285
 
285
 
286
macro   udelay msec {
286
macro   udelay msec {
287
 
287
 
288
        push    esi
288
        push    esi
289
        mov     esi, msec
289
        mov     esi, msec
290
        call    Sleep
290
        call    Sleep
291
        pop     esi
291
        pop     esi
292
 
292
 
293
}
293
}
294
 
294
 
295
macro   WRITE_GMII_REG  RegAddr, value {
295
macro   WRITE_GMII_REG  RegAddr, value {
296
 
296
 
297
        set_io  REG_PHYAR
297
        set_io  REG_PHYAR
298
        if      value eq ax
298
        if      value eq ax
299
        and     eax, 0x0000ffff
299
        and     eax, 0x0000ffff
300
        or      eax, 0x80000000 + (RegAddr shl 16)
300
        or      eax, 0x80000000 + (RegAddr shl 16)
301
        else
301
        else
302
        mov     eax, 0x80000000 + (RegAddr shl 16) + value
302
        mov     eax, 0x80000000 + (RegAddr shl 16) + value
303
        end if
303
        end if
304
        out     dx, eax
304
        out     dx, eax
305
 
305
 
306
        call    PHY_WAIT_WRITE
306
        call    PHY_WAIT_WRITE
307
}
307
}
308
 
308
 
309
macro   READ_GMII_REG  RegAddr {
309
macro   READ_GMII_REG  RegAddr {
310
 
310
 
311
local   .error, .done
311
local   .error, .done
312
 
312
 
313
        set_io  REG_PHYAR
313
        set_io  REG_PHYAR
314
        mov     eax, RegAddr shl 16
314
        mov     eax, RegAddr shl 16
315
        out     dx, eax
315
        out     dx, eax
316
 
316
 
317
        call    PHY_WAIT_READ
317
        call    PHY_WAIT_READ
318
        jz      .error
318
        jz      .error
319
 
319
 
320
        in      eax, dx
320
        in      eax, dx
321
        and     eax, 0xFFFF
321
        and     eax, 0xFFFF
322
        jmp     .done
322
        jmp     .done
323
 
323
 
324
  .error:
324
  .error:
325
        or      eax, -1
325
        or      eax, -1
326
  .done:
326
  .done:
327
}
327
}
328
 
328
 
329
align 4
329
align 4
330
PHY_WAIT_READ:       ; io addr must already be set to REG_PHYAR
330
PHY_WAIT_READ:       ; io addr must already be set to REG_PHYAR
331
 
331
 
332
        udelay  1        ;;;1000
332
        udelay  1        ;;;1000
333
 
333
 
334
        push    ecx
334
        push    ecx
335
        mov     ecx, 2000
335
        mov     ecx, 2000
336
        ; Check if the RTL8169 has completed writing/reading to the specified MII register
336
        ; Check if the RTL8169 has completed writing/reading to the specified MII register
337
    @@:
337
    @@:
338
        in      eax, dx
338
        in      eax, dx
339
        test    eax, 0x80000000
339
        test    eax, 0x80000000
340
        jnz     .exit
340
        jnz     .exit
341
        udelay  1        ;;;100
341
        udelay  1        ;;;100
342
        loop    @b
342
        loop    @b
343
  .exit:
343
  .exit:
344
        pop     ecx
344
        pop     ecx
345
        ret
345
        ret
346
 
346
 
347
align 4
347
align 4
348
PHY_WAIT_WRITE:       ; io addr must already be set to REG_PHYAR
348
PHY_WAIT_WRITE:       ; io addr must already be set to REG_PHYAR
349
 
349
 
350
        udelay  1        ;;;1000
350
        udelay  1        ;;;1000
351
 
351
 
352
        push    ecx
352
        push    ecx
353
        mov     ecx, 2000
353
        mov     ecx, 2000
354
        ; Check if the RTL8169 has completed writing/reading to the specified MII register
354
        ; Check if the RTL8169 has completed writing/reading to the specified MII register
355
    @@:
355
    @@:
356
        in      eax, dx
356
        in      eax, dx
357
        test    eax, 0x80000000
357
        test    eax, 0x80000000
358
        jz      .exit
358
        jz      .exit
359
        udelay  1        ;;;100
359
        udelay  1        ;;;100
360
        loop    @b
360
        loop    @b
361
  .exit:
361
  .exit:
362
        pop     ecx
362
        pop     ecx
363
        ret
363
        ret
364
 
364
 
365
 
365
 
366
 
366
 
367
section '.flat' code readable align 16
367
section '.flat' code readable align 16
368
 
368
 
369
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
369
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
370
;;                        ;;
370
;;                        ;;
371
;; proc START             ;;
371
;; proc START             ;;
372
;;                        ;;
372
;;                        ;;
373
;; (standard driver proc) ;;
373
;; (standard driver proc) ;;
374
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
374
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
375
 
375
 
376
align 4
376
align 4
377
proc START stdcall, state:dword
377
proc START stdcall, state:dword
378
 
378
 
379
        cmp [state], 1
379
        cmp [state], 1
380
        jne .exit
380
        jne .exit
381
 
381
 
382
  .entry:
382
  .entry:
383
 
383
 
384
        DEBUGF  2,"Loading %s driver\n", my_service
384
        DEBUGF  2,"Loading %s driver\n", my_service
385
        stdcall RegService, my_service, service_proc
385
        stdcall RegService, my_service, service_proc
386
        ret
386
        ret
387
 
387
 
388
  .fail:
388
  .fail:
389
  .exit:
389
  .exit:
390
        xor eax, eax
390
        xor eax, eax
391
        ret
391
        ret
392
 
392
 
393
endp
393
endp
394
 
394
 
395
 
395
 
396
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
396
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
397
;;                        ;;
397
;;                        ;;
398
;; proc SERVICE_PROC      ;;
398
;; proc SERVICE_PROC      ;;
399
;;                        ;;
399
;;                        ;;
400
;; (standard driver proc) ;;
400
;; (standard driver proc) ;;
401
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
401
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
402
 
402
 
403
align 4
403
align 4
404
proc service_proc stdcall, ioctl:dword
404
proc service_proc stdcall, ioctl:dword
405
 
405
 
406
        mov     edx, [ioctl]
406
        mov     edx, [ioctl]
407
        mov     eax, [IOCTL.io_code]
407
        mov     eax, [IOCTL.io_code]
408
 
408
 
409
;------------------------------------------------------
409
;------------------------------------------------------
410
 
410
 
411
        cmp     eax, 0 ;SRV_GETVERSION
411
        cmp     eax, 0 ;SRV_GETVERSION
412
        jne     @F
412
        jne     @F
413
 
413
 
414
        cmp     [IOCTL.out_size], 4
414
        cmp     [IOCTL.out_size], 4
415
        jb      .fail
415
        jb      .fail
416
        mov     eax, [IOCTL.output]
416
        mov     eax, [IOCTL.output]
417
        mov     [eax], dword API_VERSION
417
        mov     [eax], dword API_VERSION
418
 
418
 
419
        xor     eax, eax
419
        xor     eax, eax
420
        ret
420
        ret
421
 
421
 
422
;------------------------------------------------------
422
;------------------------------------------------------
423
  @@:
423
  @@:
424
        cmp     eax, 1 ;SRV_HOOK
424
        cmp     eax, 1 ;SRV_HOOK
425
        jne     .fail
425
        jne     .fail
426
 
426
 
427
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
427
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
428
        jb      .fail
428
        jb      .fail
429
 
429
 
430
        mov     eax, [IOCTL.input]
430
        mov     eax, [IOCTL.input]
431
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
431
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
432
        jne     .fail                                   ; other types arent supported for this card yet
432
        jne     .fail                                   ; other types arent supported for this card yet
433
 
433
 
434
; check if the device is already listed
434
; check if the device is already listed
435
 
435
 
436
        mov     esi, device_list
436
        mov     esi, device_list
437
        mov     ecx, [devices]
437
        mov     ecx, [devices]
438
        test    ecx, ecx
438
        test    ecx, ecx
439
        jz      .firstdevice
439
        jz      .firstdevice
440
 
440
 
441
;        mov     eax, [IOCTL.input]                     ; get the pci bus and device numbers
441
;        mov     eax, [IOCTL.input]                     ; get the pci bus and device numbers
442
        mov     ax , [eax+1]                            ;
442
        mov     ax , [eax+1]                            ;
443
  .nextdevice:
443
  .nextdevice:
444
        mov     ebx, [esi]
444
        mov     ebx, [esi]
445
        cmp     al, byte[device.pci_bus]
445
        cmp     al, byte[device.pci_bus]
446
        jne     @f
446
        jne     @f
447
        cmp     ah, byte[device.pci_dev]
447
        cmp     ah, byte[device.pci_dev]
448
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
448
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
449
       @@:
449
       @@:
450
        add     esi, 4
450
        add     esi, 4
451
        loop    .nextdevice
451
        loop    .nextdevice
452
 
452
 
453
 
453
 
454
; This device doesnt have its own eth_device structure yet, lets create one
454
; This device doesnt have its own eth_device structure yet, lets create one
455
  .firstdevice:
455
  .firstdevice:
456
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
456
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
457
        jae     .fail
457
        jae     .fail
458
 
458
 
459
        allocate_and_clear ebx, device_size, .fail      ; Allocate memory to put the device structure in
459
        allocate_and_clear ebx, device_size, .fail      ; Allocate memory to put the device structure in
460
 
460
 
461
; Fill in the direct call addresses into the struct
461
; Fill in the direct call addresses into the struct
462
 
462
 
463
        mov     [device.reset], reset
463
        mov     [device.reset], reset
464
        mov     [device.transmit], transmit
464
        mov     [device.transmit], transmit
465
        mov     [device.unload], unload
465
        mov     [device.unload], unload
466
        mov     [device.name], my_service
466
        mov     [device.name], my_service
467
 
467
 
468
; save the pci bus and device numbers
468
; save the pci bus and device numbers
469
 
469
 
470
        mov     eax, [IOCTL.input]
470
        mov     eax, [IOCTL.input]
471
        movzx   ecx, byte[eax+1]
471
        movzx   ecx, byte[eax+1]
472
        mov     [device.pci_bus], ecx
472
        mov     [device.pci_bus], ecx
473
        movzx   ecx, byte[eax+2]
473
        movzx   ecx, byte[eax+2]
474
        mov     [device.pci_dev], ecx
474
        mov     [device.pci_dev], ecx
475
 
475
 
476
; Now, it's time to find the base io addres of the PCI device
476
; Now, it's time to find the base io addres of the PCI device
477
 
477
 
478
        PCI_find_io
478
        PCI_find_io
479
        mov     [tpc.mmio_addr], eax    ; CHECKME
479
        mov     [tpc.mmio_addr], eax    ; CHECKME
480
 
480
 
481
; We've found the io address, find IRQ now
481
; We've found the io address, find IRQ now
482
 
482
 
483
        PCI_find_irq
483
        PCI_find_irq
484
 
484
 
485
        DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
485
        DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
486
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:8
486
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:8
487
 
487
 
488
; Ok, the eth_device structure is ready, let's probe the device
488
; Ok, the eth_device structure is ready, let's probe the device
489
; Because initialization fires IRQ, IRQ handler must be aware of this device
489
; Because initialization fires IRQ, IRQ handler must be aware of this device
490
        mov     eax, [devices]                                          ; Add the device structure to our device list
490
        mov     eax, [devices]                                          ; Add the device structure to our device list
491
        mov     [device_list + 4*eax], ebx                              ; (IRQ handler uses this list to find device)
491
        mov     [device_list + 4*eax], ebx                              ; (IRQ handler uses this list to find device)
492
        inc     [devices]                                               ;
492
        inc     [devices]                                               ;
493
 
493
 
494
        call    probe                                                   ; this function will output in eax
494
        call    probe                                                   ; this function will output in eax
495
        test    eax, eax
495
        test    eax, eax
496
        jnz     .err2                                                   ; If an error occured, exit
496
        jnz     .err2                                                   ; If an error occured, exit
497
 
497
 
498
        mov     [device.type], NET_TYPE_ETH
498
        mov     [device.type], NET_TYPE_ETH
499
        call    NetRegDev
499
        call    NetRegDev
500
 
500
 
501
        cmp     eax, -1
501
        cmp     eax, -1
502
        je      .destroy
502
        je      .destroy
503
 
503
 
504
        ret
504
        ret
505
 
505
 
506
; If the device was already loaded, find the device number and return it in eax
506
; If the device was already loaded, find the device number and return it in eax
507
 
507
 
508
  .find_devicenum:
508
  .find_devicenum:
509
        DEBUGF  2,"Trying to find device number of already registered device\n"
509
        DEBUGF  2,"Trying to find device number of already registered device\n"
510
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
510
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
511
                                                                        ; into a device number in edi
511
                                                                        ; into a device number in edi
512
        mov     eax, edi                                                ; Application wants it in eax instead
512
        mov     eax, edi                                                ; Application wants it in eax instead
513
        DEBUGF  2,"Kernel says: %u\n", eax
513
        DEBUGF  2,"Kernel says: %u\n", eax
514
        ret
514
        ret
515
 
515
 
516
; If an error occured, remove all allocated data and exit (returning -1 in eax)
516
; If an error occured, remove all allocated data and exit (returning -1 in eax)
517
 
517
 
518
  .destroy:
518
  .destroy:
519
        ; todo: reset device into virgin state
519
        ; todo: reset device into virgin state
520
 
520
 
521
  .err2:
521
  .err2:
522
        dec     [devices]
522
        dec     [devices]
523
  .err:
523
  .err:
524
        DEBUGF  2,"removing device structure\n"
524
        DEBUGF  2,"removing device structure\n"
525
        stdcall KernelFree, ebx
525
        stdcall KernelFree, ebx
526
  .fail:
526
  .fail:
527
        or      eax, -1
527
        or      eax, -1
528
        ret
528
        ret
529
 
529
 
530
;------------------------------------------------------
530
;------------------------------------------------------
531
endp
531
endp
532
 
532
 
533
 
533
 
534
align 4
534
align 4
535
unload:
535
unload:
536
 
536
 
537
        ret
537
        ret
538
 
538
 
539
 
539
 
540
align 4
540
align 4
541
init_board:
541
init_board:
542
 
542
 
543
        DEBUGF  1,"init_board\n"
543
        DEBUGF  1,"init_board\n"
544
 
544
 
545
        PCI_make_bus_master
545
        PCI_make_bus_master
546
 
546
 
547
        ; Soft reset the chip
547
        ; Soft reset the chip
548
        set_io  0
548
        set_io  0
549
        set_io  REG_ChipCmd
549
        set_io  REG_ChipCmd
550
        mov     al, CMD_Reset
550
        mov     al, CMD_Reset
551
        out     dx, al
551
        out     dx, al
552
 
552
 
553
        ; Check that the chip has finished the reset
553
        ; Check that the chip has finished the reset
554
        mov     ecx, 1000
554
        mov     ecx, 1000
555
        set_io  REG_ChipCmd
555
        set_io  REG_ChipCmd
556
    @@: in      al, dx
556
    @@: in      al, dx
557
        test    al, CMD_Reset
557
        test    al, CMD_Reset
558
        jz      @f
558
        jz      @f
559
        udelay  10
559
        udelay  10
560
        loop    @b
560
        loop    @b
561
    @@:
561
    @@:
562
        ; identify config method
562
        ; identify config method
563
        set_io  REG_TxConfig
563
        set_io  REG_TxConfig
564
        in      eax, dx
564
        in      eax, dx
565
        and     eax, 0x7c800000
565
        and     eax, 0x7c800000
566
        DEBUGF  1,"init_board: TxConfig & 0x7c800000 = 0x%x\n", eax
566
        DEBUGF  1,"init_board: TxConfig & 0x7c800000 = 0x%x\n", eax
567
        mov     esi, mac_info-8
567
        mov     esi, mac_info-8
568
    @@: add     esi, 8
568
    @@: add     esi, 8
569
        mov     ecx, eax
569
        mov     ecx, eax
570
        and     ecx, [esi]
570
        and     ecx, [esi]
571
        cmp     ecx, [esi]
571
        cmp     ecx, [esi]
572
        jne     @b
572
        jne     @b
573
        mov     eax, [esi+4]
573
        mov     eax, [esi+4]
574
        mov     [tpc.mcfg], eax
574
        mov     [tpc.mcfg], eax
575
 
575
 
576
        mov     [tpc.pcfg], PCFG_METHOD_3
576
        mov     [tpc.pcfg], PCFG_METHOD_3
577
        READ_GMII_REG 3
577
        READ_GMII_REG 3
578
        and     al, 0x0f
578
        and     al, 0x0f
579
        or      al, al
579
        or      al, al
580
        jnz     @f
580
        jnz     @f
581
        mov     [tpc.pcfg], PCFG_METHOD_1
581
        mov     [tpc.pcfg], PCFG_METHOD_1
582
        jmp     .pconf
582
        jmp     .pconf
583
    @@: dec     al
583
    @@: dec     al
584
        jnz     .pconf
584
        jnz     .pconf
585
        mov     [tpc.pcfg], PCFG_METHOD_2
585
        mov     [tpc.pcfg], PCFG_METHOD_2
586
  .pconf:
586
  .pconf:
587
 
587
 
588
        ; identify chip attached to board
588
        ; identify chip attached to board
589
        mov     ecx, 10
589
        mov     ecx, 10
590
        mov     eax, [tpc.mcfg]
590
        mov     eax, [tpc.mcfg]
591
    @@: dec     ecx
591
    @@: dec     ecx
592
        js      @f
592
        js      @f
593
        cmp     eax, [rtl_chip_info + ecx*8]
593
        cmp     eax, [rtl_chip_info + ecx*8]
594
        jne     @b
594
        jne     @b
595
        mov     [tpc.chipset], ecx
595
        mov     [tpc.chipset], ecx
596
        jmp     .match
596
        jmp     .match
597
    @@:
597
    @@:
598
        ; if unknown chip, assume array element #0, original RTL-8169 in this case
598
        ; if unknown chip, assume array element #0, original RTL-8169 in this case
599
        DEBUGF  1,"init_board: PCI device: unknown chip version, assuming RTL-8169\n"
599
        DEBUGF  1,"init_board: PCI device: unknown chip version, assuming RTL-8169\n"
600
        set_io  REG_TxConfig
600
        set_io  REG_TxConfig
601
        in      eax, dx
601
        in      eax, dx
602
        DEBUGF  1,"init_board: PCI device: TxConfig = 0x%x\n", eax
602
        DEBUGF  1,"init_board: PCI device: TxConfig = 0x%x\n", eax
603
 
603
 
604
        mov     [tpc.chipset],  0
604
        mov     [tpc.chipset],  0
605
 
605
 
606
        xor     eax, eax
606
        xor     eax, eax
607
        inc     eax
607
        inc     eax
608
        ret
608
        ret
609
 
609
 
610
  .match:
610
  .match:
611
        DEBUGF  1,"init_board: chipset=%u\n", ecx
611
        DEBUGF  1,"init_board: chipset=%u\n", ecx
612
        xor     eax,eax
612
        xor     eax,eax
613
        ret
613
        ret
614
 
614
 
615
 
615
 
616
 
616
 
617
;***************************************************************************
617
;***************************************************************************
618
;   Function
618
;   Function
619
;      probe
619
;      probe
620
;   Description
620
;   Description
621
;      Searches for an ethernet card, enables it and clears the rx buffer
621
;      Searches for an ethernet card, enables it and clears the rx buffer
622
;      If a card was found, it enables the ethernet -> TCPIP link
622
;      If a card was found, it enables the ethernet -> TCPIP link
623
;   Destroyed registers
623
;   Destroyed registers
624
;      eax, ebx, ecx, edx
624
;      eax, ebx, ecx, edx
625
;
625
;
626
;***************************************************************************
626
;***************************************************************************
627
align 4
627
align 4
628
probe:
628
probe:
629
 
629
 
630
        DEBUGF  1,"probe\n"
630
        DEBUGF  1,"probe\n"
631
 
631
 
632
        call    init_board
632
        call    init_board
633
        call    read_mac
633
        call    read_mac
634
        call    PHY_config
634
        call    PHY_config
635
 
635
 
636
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
636
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
637
        set_io  0
637
        set_io  0
638
        set_io  0x82
638
        set_io  0x82
639
        mov     al, 0x01
639
        mov     al, 0x01
640
        out     dx, al
640
        out     dx, al
641
        cmp     [tpc.mcfg], MCFG_METHOD_03
641
        cmp     [tpc.mcfg], MCFG_METHOD_03
642
        jae     @f
642
        jae     @f
643
;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
643
;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
644
;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
644
;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
645
   @@:
645
   @@:
646
        cmp     [tpc.mcfg], MCFG_METHOD_02
646
        cmp     [tpc.mcfg], MCFG_METHOD_02
647
        jne     @f
647
        jne     @f
648
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
648
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
649
        set_io  0x82
649
        set_io  0x82
650
        mov     al, 0x01
650
        mov     al, 0x01
651
        out     dx, al
651
        out     dx, al
652
;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
652
;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
653
        WRITE_GMII_REG 0x0b, 0x0000      ; w 0x0b 15 0 0
653
        WRITE_GMII_REG 0x0b, 0x0000      ; w 0x0b 15 0 0
654
    @@:
654
    @@:
655
        ; if TBI is not enabled
655
        ; if TBI is not enabled
656
        set_io  0
656
        set_io  0
657
        set_io  REG_PHYstatus
657
        set_io  REG_PHYstatus
658
        in      al, dx
658
        in      al, dx
659
        test    al, PHYS_TBI_Enable
659
        test    al, PHYS_TBI_Enable
660
        jz      .tbi_dis
660
        jz      .tbi_dis
661
        READ_GMII_REG PHY_AUTO_NEGO_REG
661
        READ_GMII_REG PHY_AUTO_NEGO_REG
662
 
662
 
663
        ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
663
        ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
664
        and     eax, 0x0C1F
664
        and     eax, 0x0C1F
665
        or      eax, PHY_Cap_10_Half or PHY_Cap_10_Full or PHY_Cap_100_Half or PHY_Cap_100_Full
665
        or      eax, PHY_Cap_10_Half or PHY_Cap_10_Full or PHY_Cap_100_Half or PHY_Cap_100_Full
666
        WRITE_GMII_REG PHY_AUTO_NEGO_REG, ax
666
        WRITE_GMII_REG PHY_AUTO_NEGO_REG, ax
667
 
667
 
668
        ; enable 1000 Full Mode
668
        ; enable 1000 Full Mode
669
        WRITE_GMII_REG PHY_1000_CTRL_REG, PHY_Cap_1000_Full or PHY_Cap_1000_Half ; rtl8168
669
        WRITE_GMII_REG PHY_1000_CTRL_REG, PHY_Cap_1000_Full or PHY_Cap_1000_Half ; rtl8168
670
 
670
 
671
        ; Enable auto-negotiation and restart auto-nigotiation
671
        ; Enable auto-negotiation and restart auto-nigotiation
672
        WRITE_GMII_REG PHY_CTRL_REG, PHY_Enable_Auto_Nego or PHY_Restart_Auto_Nego
672
        WRITE_GMII_REG PHY_CTRL_REG, PHY_Enable_Auto_Nego or PHY_Restart_Auto_Nego
673
 
673
 
674
        udelay  100
674
        udelay  100
675
        mov     ecx, 10000
675
        mov     ecx, 10000
676
        ; wait for auto-negotiation process
676
        ; wait for auto-negotiation process
677
    @@: dec     ecx
677
    @@: dec     ecx
678
        jz      @f
678
        jz      @f
679
        set_io  0
679
        set_io  0
680
        READ_GMII_REG PHY_STAT_REG
680
        READ_GMII_REG PHY_STAT_REG
681
        udelay  100
681
        udelay  100
682
        test    eax, PHY_Auto_Neco_Comp
682
        test    eax, PHY_Auto_Neco_Comp
683
        jz      @b
683
        jz      @b
684
        set_io  REG_PHYstatus
684
        set_io  REG_PHYstatus
685
        in      al, dx
685
        in      al, dx
686
        jmp     @f
686
        jmp     @f
687
  .tbi_dis:
687
  .tbi_dis:
688
        udelay  100
688
        udelay  100
689
    @@:
689
    @@:
690
 
690
 
691
 
691
 
692
;***************************************************************************
692
;***************************************************************************
693
;   Function
693
;   Function
694
;      rt8169_reset
694
;      rt8169_reset
695
;   Description
695
;   Description
696
;      Place the chip (ie, the ethernet card) into a virgin state
696
;      Place the chip (ie, the ethernet card) into a virgin state
697
;   Destroyed registers
697
;   Destroyed registers
698
;      eax, ebx, ecx, edx
698
;      eax, ebx, ecx, edx
699
;
699
;
700
;***************************************************************************
700
;***************************************************************************
701
align 4
701
align 4
702
reset:
702
reset:
703
 
703
 
704
        DEBUGF  1,"reset\n"
704
        DEBUGF  1,"reset\n"
705
 
705
 
706
        lea     eax, [device.tx_ring]
706
        lea     eax, [device.tx_ring]
707
        mov     [tpc.TxDescArrays], eax
707
        mov     [tpc.TxDescArrays], eax
708
        mov     [tpc.TxDescArray], eax
708
        mov     [tpc.TxDescArray], eax
709
 
709
 
710
        lea     eax, [device.rx_ring]
710
        lea     eax, [device.rx_ring]
711
        mov     [tpc.RxDescArrays], eax
711
        mov     [tpc.RxDescArrays], eax
712
        mov     [tpc.RxDescArray], eax
712
        mov     [tpc.RxDescArray], eax
713
 
713
 
714
        call    init_ring
714
        call    init_ring
715
        call    hw_start
715
        call    hw_start
716
 
716
 
717
; clear packet/byte counters
717
; clear packet/byte counters
718
 
718
 
719
        xor     eax, eax
719
        xor     eax, eax
720
        lea     edi, [device.bytes_tx]
720
        lea     edi, [device.bytes_tx]
721
        mov     ecx, 6
721
        mov     ecx, 6
722
        rep     stosd
722
        rep     stosd
723
 
723
 
724
        mov     [device.mtu], 1500
724
        mov     [device.mtu], 1500
725
 
725
 
726
; Set link state to unknown
726
; Set link state to unknown
727
        mov     [device.state], ETH_LINK_UNKOWN
727
        mov     [device.state], ETH_LINK_UNKOWN
728
 
728
 
729
        xor     eax, eax
729
        xor     eax, eax
730
        ret
730
        ret
731
 
731
 
732
 
732
 
733
 
733
 
734
 
734
 
735
 
735
 
736
align 4
736
align 4
737
PHY_config:
737
PHY_config:
738
 
738
 
739
        DEBUGF  1,"hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[tpc.mcfg],[tpc.pcfg]
739
        DEBUGF  1,"hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[tpc.mcfg],[tpc.pcfg]
740
 
740
 
741
        cmp     [tpc.mcfg], MCFG_METHOD_04
741
        cmp     [tpc.mcfg], MCFG_METHOD_04
742
        jne     .not_4
742
        jne     .not_4
743
        set_io  0
743
        set_io  0
744
;       WRITE_GMII_REG 0x1F, 0x0001
744
;       WRITE_GMII_REG 0x1F, 0x0001
745
;       WRITE_GMII_REG 0x1b, 0x841e
745
;       WRITE_GMII_REG 0x1b, 0x841e
746
;       WRITE_GMII_REG 0x0e, 0x7bfb
746
;       WRITE_GMII_REG 0x0e, 0x7bfb
747
;       WRITE_GMII_REG 0x09, 0x273a
747
;       WRITE_GMII_REG 0x09, 0x273a
748
        WRITE_GMII_REG 0x1F, 0x0002
748
        WRITE_GMII_REG 0x1F, 0x0002
749
        WRITE_GMII_REG 0x01, 0x90D0
749
        WRITE_GMII_REG 0x01, 0x90D0
750
        WRITE_GMII_REG 0x1F, 0x0000
750
        WRITE_GMII_REG 0x1F, 0x0000
751
        jmp     .exit
751
        jmp     .exit
752
  .not_4:
752
  .not_4:
753
        cmp     [tpc.mcfg], MCFG_METHOD_02
753
        cmp     [tpc.mcfg], MCFG_METHOD_02
754
        je      @f
754
        je      @f
755
        cmp     [tpc.mcfg], MCFG_METHOD_03
755
        cmp     [tpc.mcfg], MCFG_METHOD_03
756
        jne     .not_2_or_3
756
        jne     .not_2_or_3
757
    @@:
757
    @@:
758
        set_io  0
758
        set_io  0
759
        WRITE_GMII_REG 0x1F, 0x0001
759
        WRITE_GMII_REG 0x1F, 0x0001
760
        WRITE_GMII_REG 0x15, 0x1000
760
        WRITE_GMII_REG 0x15, 0x1000
761
        WRITE_GMII_REG 0x18, 0x65C7
761
        WRITE_GMII_REG 0x18, 0x65C7
762
        WRITE_GMII_REG 0x04, 0x0000
762
        WRITE_GMII_REG 0x04, 0x0000
763
        WRITE_GMII_REG 0x03, 0x00A1
763
        WRITE_GMII_REG 0x03, 0x00A1
764
        WRITE_GMII_REG 0x02, 0x0008
764
        WRITE_GMII_REG 0x02, 0x0008
765
        WRITE_GMII_REG 0x01, 0x1020
765
        WRITE_GMII_REG 0x01, 0x1020
766
        WRITE_GMII_REG 0x00, 0x1000
766
        WRITE_GMII_REG 0x00, 0x1000
767
        WRITE_GMII_REG 0x04, 0x0800
767
        WRITE_GMII_REG 0x04, 0x0800
768
        WRITE_GMII_REG 0x04, 0x0000
768
        WRITE_GMII_REG 0x04, 0x0000
769
        WRITE_GMII_REG 0x04, 0x7000
769
        WRITE_GMII_REG 0x04, 0x7000
770
        WRITE_GMII_REG 0x03, 0xFF41
770
        WRITE_GMII_REG 0x03, 0xFF41
771
        WRITE_GMII_REG 0x02, 0xDE60
771
        WRITE_GMII_REG 0x02, 0xDE60
772
        WRITE_GMII_REG 0x01, 0x0140
772
        WRITE_GMII_REG 0x01, 0x0140
773
        WRITE_GMII_REG 0x00, 0x0077
773
        WRITE_GMII_REG 0x00, 0x0077
774
        WRITE_GMII_REG 0x04, 0x7800
774
        WRITE_GMII_REG 0x04, 0x7800
775
        WRITE_GMII_REG 0x04, 0x7000
775
        WRITE_GMII_REG 0x04, 0x7000
776
        WRITE_GMII_REG 0x04, 0xA000
776
        WRITE_GMII_REG 0x04, 0xA000
777
        WRITE_GMII_REG 0x03, 0xDF01
777
        WRITE_GMII_REG 0x03, 0xDF01
778
        WRITE_GMII_REG 0x02, 0xDF20
778
        WRITE_GMII_REG 0x02, 0xDF20
779
        WRITE_GMII_REG 0x01, 0xFF95
779
        WRITE_GMII_REG 0x01, 0xFF95
780
        WRITE_GMII_REG 0x00, 0xFA00
780
        WRITE_GMII_REG 0x00, 0xFA00
781
        WRITE_GMII_REG 0x04, 0xA800
781
        WRITE_GMII_REG 0x04, 0xA800
782
        WRITE_GMII_REG 0x04, 0xA000
782
        WRITE_GMII_REG 0x04, 0xA000
783
        WRITE_GMII_REG 0x04, 0xB000
783
        WRITE_GMII_REG 0x04, 0xB000
784
        WRITE_GMII_REG 0x03, 0xFF41
784
        WRITE_GMII_REG 0x03, 0xFF41
785
        WRITE_GMII_REG 0x02, 0xDE20
785
        WRITE_GMII_REG 0x02, 0xDE20
786
        WRITE_GMII_REG 0x01, 0x0140
786
        WRITE_GMII_REG 0x01, 0x0140
787
        WRITE_GMII_REG 0x00, 0x00BB
787
        WRITE_GMII_REG 0x00, 0x00BB
788
        WRITE_GMII_REG 0x04, 0xB800
788
        WRITE_GMII_REG 0x04, 0xB800
789
        WRITE_GMII_REG 0x04, 0xB000
789
        WRITE_GMII_REG 0x04, 0xB000
790
        WRITE_GMII_REG 0x04, 0xF000
790
        WRITE_GMII_REG 0x04, 0xF000
791
        WRITE_GMII_REG 0x03, 0xDF01
791
        WRITE_GMII_REG 0x03, 0xDF01
792
        WRITE_GMII_REG 0x02, 0xDF20
792
        WRITE_GMII_REG 0x02, 0xDF20
793
        WRITE_GMII_REG 0x01, 0xFF95
793
        WRITE_GMII_REG 0x01, 0xFF95
794
        WRITE_GMII_REG 0x00, 0xBF00
794
        WRITE_GMII_REG 0x00, 0xBF00
795
        WRITE_GMII_REG 0x04, 0xF800
795
        WRITE_GMII_REG 0x04, 0xF800
796
        WRITE_GMII_REG 0x04, 0xF000
796
        WRITE_GMII_REG 0x04, 0xF000
797
        WRITE_GMII_REG 0x04, 0x0000
797
        WRITE_GMII_REG 0x04, 0x0000
798
        WRITE_GMII_REG 0x1F, 0x0000
798
        WRITE_GMII_REG 0x1F, 0x0000
799
        WRITE_GMII_REG 0x0B, 0x0000
799
        WRITE_GMII_REG 0x0B, 0x0000
800
        jmp     .exit
800
        jmp     .exit
801
  .not_2_or_3:
801
  .not_2_or_3:
802
        DEBUGF  1,"tpc.mcfg=%d, discard hw PHY config\n", [tpc.mcfg]
802
        DEBUGF  1,"tpc.mcfg=%d, discard hw PHY config\n", [tpc.mcfg]
803
  .exit:
803
  .exit:
804
        ret
804
        ret
805
 
805
 
806
 
806
 
807
 
807
 
808
align 4
808
align 4
809
set_rx_mode:
809
set_rx_mode:
810
 
810
 
811
        DEBUGF  1,"set_rx_mode\n"
811
        DEBUGF  1,"set_rx_mode\n"
812
 
812
 
813
        ; IFF_ALLMULTI
813
        ; IFF_ALLMULTI
814
        ; Too many to filter perfectly -- accept all multicasts
814
        ; Too many to filter perfectly -- accept all multicasts
815
        set_io  0
815
        set_io  0
816
        set_io  REG_RxConfig
816
        set_io  REG_RxConfig
817
        in      eax, dx
817
        in      eax, dx
818
        mov     ecx, [tpc.chipset]
818
        mov     ecx, [tpc.chipset]
819
        and     eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
819
        and     eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
820
        or      eax, rx_config or (RXM_AcceptBroadcast or RXM_AcceptMulticast or RXM_AcceptMyPhys)
820
        or      eax, rx_config or (RXM_AcceptBroadcast or RXM_AcceptMulticast or RXM_AcceptMyPhys)
821
        out     dx, eax
821
        out     dx, eax
822
 
822
 
823
        ; Multicast hash filter
823
        ; Multicast hash filter
824
        set_io  REG_MAR0 + 0
824
        set_io  REG_MAR0 + 0
825
        or      eax, -1
825
        or      eax, -1
826
        out     dx, eax
826
        out     dx, eax
827
        set_io  REG_MAR0 + 4
827
        set_io  REG_MAR0 + 4
828
        out     dx, eax
828
        out     dx, eax
829
 
829
 
830
        ret
830
        ret
831
 
831
 
832
 
832
 
833
align 4
833
align 4
834
init_ring:
834
init_ring:
835
 
835
 
836
        DEBUGF  1,"init_ring\n"
836
        DEBUGF  1,"init_ring\n"
837
 
837
 
838
        xor     eax, eax
838
        xor     eax, eax
839
        mov     [tpc.cur_rx], eax
839
        mov     [tpc.cur_rx], eax
840
        mov     [tpc.cur_tx], eax
840
        mov     [tpc.cur_tx], eax
841
 
841
 
842
        lea     edi, [device.tx_ring]
842
        lea     edi, [device.tx_ring]
843
        mov     ecx, (NUM_TX_DESC * tx_desc.size) / 4
843
        mov     ecx, (NUM_TX_DESC * tx_desc.size) / 4
844
        rep     stosd
844
        rep     stosd
845
 
845
 
846
        lea     edi, [device.rx_ring]
846
        lea     edi, [device.rx_ring]
847
        mov     ecx, (NUM_RX_DESC * rx_desc.size) / 4
847
        mov     ecx, (NUM_RX_DESC * rx_desc.size) / 4
848
        rep     stosd
848
        rep     stosd
849
 
849
 
850
        mov     edi, [tpc.RxDescArray]
850
        mov     edi, [tpc.RxDescArray]
851
        mov     ecx, NUM_RX_DESC
851
        mov     ecx, NUM_RX_DESC
852
  .loop:
852
  .loop:
853
        push    ecx
853
        push    ecx
854
        stdcall KernelAlloc, RX_BUF_SIZE
854
        stdcall KernelAlloc, RX_BUF_SIZE
855
        mov     [edi + rx_desc.buf_soft_addr], eax
855
        mov     [edi + rx_desc.buf_soft_addr], eax
856
        call    GetPgAddr
856
        call    GetPgAddr
857
        mov     dword [edi + rx_desc.buf_addr], eax
857
        mov     dword [edi + rx_desc.buf_addr], eax
858
        mov     [edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE
858
        mov     [edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE
859
        add     edi, rx_desc.size
859
        add     edi, rx_desc.size
860
        pop     ecx
860
        pop     ecx
861
        loop    .loop
861
        loop    .loop
862
        or      [edi - rx_desc.size + rx_desc.status], DSB_EORbit
862
        or      [edi - rx_desc.size + rx_desc.status], DSB_EORbit
863
 
863
 
864
        ret
864
        ret
865
 
865
 
866
 
866
 
867
align 4
867
align 4
868
hw_start:
868
hw_start:
869
 
869
 
870
        DEBUGF  1,"hw_start\n"
870
        DEBUGF  1,"hw_start\n"
871
 
871
 
872
; attach int handler
872
; attach int handler
873
        movzx   eax, [device.irq_line]
873
        movzx   eax, [device.irq_line]
874
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
874
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
875
        stdcall AttachIntHandler, eax, int_handler, dword 0
875
        stdcall AttachIntHandler, eax, int_handler, dword 0
876
 
876
 
877
        ; Soft reset the chip
877
        ; Soft reset the chip
878
        set_io  0
878
        set_io  0
879
        set_io  REG_ChipCmd
879
        set_io  REG_ChipCmd
880
        mov     al, CMD_Reset
880
        mov     al, CMD_Reset
881
        out     dx, al
881
        out     dx, al
882
 
882
 
883
        DEBUGF  1,"Waiting for chip to reset... "
883
        DEBUGF  1,"Waiting for chip to reset... "
884
        ; Check that the chip has finished the reset
884
        ; Check that the chip has finished the reset
885
        mov     ecx, 1000
885
        mov     ecx, 1000
886
        set_io  REG_ChipCmd
886
        set_io  REG_ChipCmd
887
    @@: in      al, dx
887
    @@: in      al, dx
888
        test    al, CMD_Reset
888
        test    al, CMD_Reset
889
        jz      @f
889
        jz      @f
890
        udelay  10
890
        udelay  10
891
        loop    @b
891
        loop    @b
892
    @@:
892
    @@:
893
        DEBUGF  1,"done!\n"
893
        DEBUGF  1,"done!\n"
894
 
894
 
895
        set_io  REG_Cfg9346
895
        set_io  REG_Cfg9346
896
        mov     al, CFG_9346_Unlock
896
        mov     al, CFG_9346_Unlock
897
        out     dx, al
897
        out     dx, al
898
 
898
 
899
        set_io  REG_ChipCmd
899
        set_io  REG_ChipCmd
900
        mov     al, CMD_TxEnb or CMD_RxEnb
900
        mov     al, CMD_TxEnb or CMD_RxEnb
901
        out     dx, al
901
        out     dx, al
902
 
902
 
903
        set_io  REG_ETThReg
903
        set_io  REG_ETThReg
904
        mov     al, ETTh
904
        mov     al, ETTh
905
        out     dx, al
905
        out     dx, al
906
 
906
 
907
        ; For gigabit rtl8169
907
        ; For gigabit rtl8169
908
        set_io  REG_RxMaxSize
908
        set_io  REG_RxMaxSize
909
        mov     ax, RxPacketMaxSize
909
        mov     ax, RxPacketMaxSize
910
        out     dx, ax
910
        out     dx, ax
911
 
911
 
912
        ; Set Rx Config register
912
        ; Set Rx Config register
913
        set_io  REG_RxConfig
913
        set_io  REG_RxConfig
914
        in      ax, dx
914
        in      ax, dx
915
        mov     ecx, [tpc.chipset]
915
        mov     ecx, [tpc.chipset]
916
        and     eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
916
        and     eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
917
        or      eax, rx_config
917
        or      eax, rx_config
918
        out     dx, eax
918
        out     dx, eax
919
 
919
 
920
        ; Set DMA burst size and Interframe Gap Time
920
        ; Set DMA burst size and Interframe Gap Time
921
        set_io  REG_TxConfig
921
        set_io  REG_TxConfig
922
        mov     eax, (TX_DMA_BURST shl TXC_DMAShift) or (InterFrameGap shl TXC_InterFrameGapShift)
922
        mov     eax, (TX_DMA_BURST shl TXC_DMAShift) or (InterFrameGap shl TXC_InterFrameGapShift)
923
        out     dx, eax
923
        out     dx, eax
924
 
924
 
925
        set_io  REG_CPlusCmd
925
        set_io  REG_CPlusCmd
926
        in      ax, dx
926
        in      ax, dx
927
        out     dx, ax
927
        out     dx, ax
928
 
928
 
929
        in      ax, dx
929
        in      ax, dx
930
        or      ax, 1 shl 3
930
        or      ax, 1 shl 3
931
        cmp     [tpc.mcfg], MCFG_METHOD_02
931
        cmp     [tpc.mcfg], MCFG_METHOD_02
932
        jne     @f
932
        jne     @f
933
        cmp     [tpc.mcfg], MCFG_METHOD_03
933
        cmp     [tpc.mcfg], MCFG_METHOD_03
934
        jne     @f
934
        jne     @f
935
        or      ax,1 shl 14
935
        or      ax,1 shl 14
936
        DEBUGF  1,"Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
936
        DEBUGF  1,"Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
937
        jmp     .set
937
        jmp     .set
938
    @@:
938
    @@:
939
        DEBUGF  1,"Set MAC Reg C+CR Offset 0xE0: bit-3\n"
939
        DEBUGF  1,"Set MAC Reg C+CR Offset 0xE0: bit-3\n"
940
  .set:
940
  .set:
941
        set_io  REG_CPlusCmd
941
        set_io  REG_CPlusCmd
942
        out     dx, ax
942
        out     dx, ax
943
 
943
 
944
        set_io  0xE2
944
        set_io  0xE2
945
;        mov     ax, 0x1517
945
;        mov     ax, 0x1517
946
;        out     dx, ax
946
;        out     dx, ax
947
;        mov     ax, 0x152a
947
;        mov     ax, 0x152a
948
;        out     dx, ax
948
;        out     dx, ax
949
;        mov     ax, 0x282a
949
;        mov     ax, 0x282a
950
;        out     dx, ax
950
;        out     dx, ax
951
        xor     ax, ax
951
        xor     ax, ax
952
        out     dx, ax
952
        out     dx, ax
953
 
953
 
954
        xor     eax, eax
954
        xor     eax, eax
955
        mov     [tpc.cur_rx], eax
955
        mov     [tpc.cur_rx], eax
956
        lea     eax, [device.tx_ring]
956
        lea     eax, [device.tx_ring]
957
        GetRealAddr
957
        GetRealAddr
958
        set_io  REG_TxDescStartAddr
958
        set_io  REG_TxDescStartAddr
959
        out     dx, eax
959
        out     dx, eax
-
 
960
        set_io  REG_TxDescStartAddr + 4
-
 
961
        xor     eax, eax
-
 
962
        out     dx, eax
960
 
963
 
961
        lea     eax, [device.rx_ring]
964
        lea     eax, [device.rx_ring]
962
        GetRealAddr
965
        GetRealAddr
963
        set_io  REG_RxDescStartAddr
966
        set_io  REG_RxDescStartAddr
964
        out     dx, eax
967
        out     dx, eax
-
 
968
        xor     eax, eax
-
 
969
        set_io  REG_RxDescStartAddr + 4
-
 
970
        out     dx, eax
965
 
971
 
966
        set_io  REG_Cfg9346
972
        set_io  REG_Cfg9346
967
        mov     al, CFG_9346_Lock
973
        mov     al, CFG_9346_Lock
968
        out     dx, al
974
        out     dx, al
969
 
975
 
970
        udelay  10
976
        udelay  10
971
 
977
 
972
        xor     eax, eax
978
        xor     eax, eax
973
        set_io  REG_RxMissed
979
        set_io  REG_RxMissed
974
        out     dx, eax
980
        out     dx, eax
975
 
981
 
976
        call    set_rx_mode
982
        call    set_rx_mode
977
 
983
 
978
        set_io  0
984
        set_io  0
979
        ; no early-rx interrupts
985
        ; no early-rx interrupts
980
        set_io  REG_MultiIntr
986
        set_io  REG_MultiIntr
981
        in      ax, dx
987
        in      ax, dx
982
        and     ax, 0xF000
988
        and     ax, 0xF000
983
        out     dx, ax
989
        out     dx, ax
984
 
990
 
985
        ; set interrupt mask
991
        ; set interrupt mask
986
        set_io  REG_IntrMask
992
        set_io  REG_IntrMask
987
        mov     ax, intr_mask
993
        mov     ax, intr_mask
988
        out     dx, ax
994
        out     dx, ax
989
 
995
 
990
        xor     eax, eax
996
        xor     eax, eax
991
        ret
997
        ret
992
 
998
 
993
 
999
 
994
align 4
1000
align 4
995
read_mac:
1001
read_mac:
996
 
1002
 
997
        set_io  0
1003
        set_io  0
998
        set_io  REG_MAC0
1004
        set_io  REG_MAC0
999
        xor     ecx, ecx
1005
        xor     ecx, ecx
1000
        lea     edi, [device.mac]
1006
        lea     edi, [device.mac]
1001
        mov     ecx, 6
1007
        mov     ecx, 6
1002
 
1008
 
1003
        ; Get MAC address. FIXME: read EEPROM
1009
        ; Get MAC address. FIXME: read EEPROM
1004
    @@: in      al, dx
1010
    @@: in      al, dx
1005
        stosb
1011
        stosb
1006
        inc     edx
1012
        inc     edx
1007
        loop    @r
1013
        loop    @r
1008
 
1014
 
1009
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1015
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1010
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
1016
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
1011
 
1017
 
1012
        ret
1018
        ret
1013
 
1019
 
1014
align 4
1020
align 4
1015
write_mac:
1021
write_mac:
1016
 
1022
 
1017
        ret     6
1023
        ret     6
1018
 
1024
 
1019
 
1025
 
1020
 
1026
 
1021
 
1027
 
1022
 
1028
 
1023
;***************************************************************************
1029
;***************************************************************************
1024
;   Function
1030
;   Function
1025
;      transmit
1031
;      transmit
1026
;   Description
1032
;   Description
1027
;      Transmits a packet of data via the ethernet card
1033
;      Transmits a packet of data via the ethernet card
1028
;
1034
;
1029
;   Destroyed registers
1035
;   Destroyed registers
1030
;      eax, edx, esi, edi
1036
;      eax, edx, esi, edi
1031
;
1037
;
1032
;***************************************************************************
1038
;***************************************************************************
1033
align 4
1039
align 4
1034
transmit:
1040
transmit:
1035
 
1041
 
1036
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
1042
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
1037
        mov     eax, [esp+4]
1043
        mov     eax, [esp+4]
1038
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1044
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1039
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1045
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1040
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1046
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1041
        [eax+13]:2,[eax+12]:2
1047
        [eax+13]:2,[eax+12]:2
1042
 
1048
 
1043
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
1049
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
1044
        ja      .fail
1050
        ja      .fail
1045
 
1051
 
1046
;----------------------------------
1052
;----------------------------------
1047
; Find currentTX descriptor address
1053
; Find currentTX descriptor address
1048
 
1054
 
1049
        mov     eax, tx_desc.size
1055
        mov     eax, tx_desc.size
1050
        mul     [tpc.cur_tx]
1056
        mul     [tpc.cur_tx]
1051
        lea     esi, [eax + device.tx_ring]
1057
        lea     esi, [eax + device.tx_ring]
1052
 
1058
 
1053
        DEBUGF  1,"Using TX desc: %x\n", esi
1059
        DEBUGF  1,"Using TX desc: %x\n", esi
1054
 
1060
 
1055
;---------------------------
1061
;---------------------------
1056
; Program the packet pointer
1062
; Program the packet pointer
1057
 
1063
 
1058
        mov     eax, [esp + 4]
1064
        mov     eax, [esp + 4]
1059
        mov     [esi + tx_desc.buf_soft_addr], eax
1065
        mov     [esi + tx_desc.buf_soft_addr], eax
1060
        GetRealAddr
1066
        GetRealAddr
1061
        mov     dword [esi + tx_desc.buf_addr], eax
1067
        mov     dword [esi + tx_desc.buf_addr], eax
1062
 
1068
 
1063
;------------------------
1069
;------------------------
1064
; Program the packet size
1070
; Program the packet size
1065
 
1071
 
1066
        mov     eax, [esp + 8]
1072
        mov     eax, [esp + 8]
1067
    @@: or      eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit
1073
    @@: or      eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit
1068
        cmp     [tpc.cur_tx], NUM_TX_DESC - 1
1074
        cmp     [tpc.cur_tx], NUM_TX_DESC - 1
1069
        jne     @f
1075
        jne     @f
1070
        or      eax, DSB_EORbit
1076
        or      eax, DSB_EORbit
1071
    @@: mov     [esi + tx_desc.status], eax
1077
    @@: mov     [esi + tx_desc.status], eax
1072
 
1078
 
1073
;-----------------------------------------
1079
;-----------------------------------------
1074
; Set the polling bit (start transmission)
1080
; Set the polling bit (start transmission)
1075
 
1081
 
1076
        set_io  0
1082
        set_io  0
1077
        set_io  REG_TxPoll
1083
        set_io  REG_TxPoll
1078
        mov     al, 0x40     ; set polling bit
1084
        mov     al, 0x40     ; set polling bit
1079
        out     dx, al
1085
        out     dx, al
1080
 
1086
 
1081
;-----------------------
1087
;-----------------------
1082
; Update TX descriptor
1088
; Update TX descriptor
1083
 
1089
 
1084
        inc     [tpc.cur_tx]
1090
        inc     [tpc.cur_tx]
1085
        and     [tpc.cur_tx], NUM_TX_DESC - 1
1091
        and     [tpc.cur_tx], NUM_TX_DESC - 1
1086
 
1092
 
1087
;-------------
1093
;-------------
1088
; Update stats
1094
; Update stats
1089
 
1095
 
1090
        inc     [device.packets_tx]
1096
        inc     [device.packets_tx]
1091
        mov     eax, [esp + 8]
1097
        mov     eax, [esp + 8]
1092
        add     dword [device.bytes_tx], eax
1098
        add     dword [device.bytes_tx], eax
1093
        adc     dword [device.bytes_tx + 4], 0
1099
        adc     dword [device.bytes_tx + 4], 0
1094
 
1100
 
1095
        xor     eax, eax
1101
        xor     eax, eax
1096
        ret     8
1102
        ret     8
1097
 
1103
 
1098
  .fail:
1104
  .fail:
1099
        DEBUGF  1,"transmit failed\n"
1105
        DEBUGF  1,"transmit failed\n"
1100
        or      eax, -1
1106
        or      eax, -1
1101
        stdcall KernelFree, [esp+4]
1107
        stdcall KernelFree, [esp+4]
1102
        ret     8
1108
        ret     8
1103
 
1109
 
1104
 
1110
 
1105
;;;DSB_OWNbit
1111
;;;DSB_OWNbit
1106
 
1112
 
1107
 
1113
 
1108
;;;;;;;;;;;;;;;;;;;;;;;
1114
;;;;;;;;;;;;;;;;;;;;;;;
1109
;;                   ;;
1115
;;                   ;;
1110
;; Interrupt handler ;;
1116
;; Interrupt handler ;;
1111
;;                   ;;
1117
;;                   ;;
1112
;;;;;;;;;;;;;;;;;;;;;;;
1118
;;;;;;;;;;;;;;;;;;;;;;;
1113
 
1119
 
1114
align 4
1120
align 4
1115
int_handler:
1121
int_handler:
1116
 
1122
 
1117
        push    ebx esi edi
1123
        push    ebx esi edi
1118
 
1124
 
1119
        DEBUGF  1,"\n%s int\n", my_service
1125
        DEBUGF  1,"\n%s int\n", my_service
1120
 
1126
 
1121
; find pointer of device wich made IRQ occur
1127
; find pointer of device wich made IRQ occur
1122
 
1128
 
1123
        mov     ecx, [devices]
1129
        mov     ecx, [devices]
1124
        test    ecx, ecx
1130
        test    ecx, ecx
1125
        jz      .nothing
1131
        jz      .nothing
1126
        mov     esi, device_list
1132
        mov     esi, device_list
1127
  .nextdevice:
1133
  .nextdevice:
1128
        mov     ebx, [esi]
1134
        mov     ebx, [esi]
1129
 
1135
 
1130
        set_io  0
1136
        set_io  0
1131
        set_io  REG_IntrStatus
1137
        set_io  REG_IntrStatus
1132
        in      ax, dx
1138
        in      ax, dx
1133
        test    ax, ax
1139
        test    ax, ax
1134
        jnz     .got_it
1140
        jnz     .got_it
1135
  .continue:
1141
  .continue:
1136
        add     esi, 4
1142
        add     esi, 4
1137
        dec     ecx
1143
        dec     ecx
1138
        jnz     .nextdevice
1144
        jnz     .nextdevice
1139
  .nothing:
1145
  .nothing:
1140
        pop     edi esi ebx
1146
        pop     edi esi ebx
1141
        xor     eax, eax
1147
        xor     eax, eax
1142
 
1148
 
1143
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1149
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1144
 
1150
 
1145
  .got_it:
1151
  .got_it:
1146
 
1152
 
1147
        DEBUGF  1,"Device: %x Status: %x ", ebx, ax
1153
        DEBUGF  1,"Device: %x Status: %x ", ebx, ax
1148
 
1154
 
1149
        cmp     ax, 0xFFFF      ; if so, hardware is no longer present
1155
        cmp     ax, 0xFFFF      ; if so, hardware is no longer present
1150
        je      .fail
1156
        je      .fail
1151
 
1157
 
1152
;--------
1158
;--------
1153
; Receive
1159
; Receive
1154
 
1160
 
1155
        test    ax, ISB_RxOK
1161
        test    ax, ISB_RxOK
1156
        jz      .no_rx
1162
        jz      .no_rx
1157
 
1163
 
1158
        push    ax
1164
        push    ax
1159
        push    ebx
1165
        push    ebx
1160
 
1166
 
1161
  .check_more:
1167
  .check_more:
1162
        pop     ebx
1168
        pop     ebx
1163
        DEBUGF  1,"ebx = 0x%x\n", ebx
1169
        DEBUGF  1,"ebx = 0x%x\n", ebx
1164
        mov     eax, rx_desc.size
1170
        mov     eax, rx_desc.size
1165
        mul     [tpc.cur_rx]
1171
        mul     [tpc.cur_rx]
1166
        lea     esi, [eax + device.rx_ring]
1172
        lea     esi, [eax + device.rx_ring]
1167
 
1173
 
1168
        DEBUGF  1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status]
1174
        DEBUGF  1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status]
1169
 
1175
 
1170
        mov     eax, [esi + rx_desc.status]
1176
        mov     eax, [esi + rx_desc.status]
1171
        test    eax, DSB_OWNbit ;;;
1177
        test    eax, DSB_OWNbit ;;;
1172
        jnz     .rx_return
1178
        jnz     .rx_return
1173
 
1179
 
1174
        DEBUGF  1,"tpc.cur_rx = %u\n", [tpc.cur_rx]
1180
        DEBUGF  1,"tpc.cur_rx = %u\n", [tpc.cur_rx]
1175
 
1181
 
1176
        test    eax, SD_RxRES
1182
        test    eax, SD_RxRES
1177
        jnz     .rx_return      ;;;;; RX error!
1183
        jnz     .rx_return      ;;;;; RX error!
1178
 
1184
 
1179
        push    ebx
1185
        push    ebx
1180
        push    .check_more
1186
        push    .check_more
1181
        and     eax, 0x00001FFF
1187
        and     eax, 0x00001FFF
1182
        add     eax, -4                         ; we dont need CRC
1188
        add     eax, -4                         ; we dont need CRC
1183
        push    eax
1189
        push    eax
1184
        DEBUGF  1,"data length = %u\n", ax
1190
        DEBUGF  1,"data length = %u\n", ax
1185
 
1191
 
1186
;-------------
1192
;-------------
1187
; Update stats
1193
; Update stats
1188
 
1194
 
1189
        add     dword [device.bytes_rx], eax
1195
        add     dword [device.bytes_rx], eax
1190
        adc     dword [device.bytes_rx + 4], 0
1196
        adc     dword [device.bytes_rx + 4], 0
1191
        inc     dword [device.packets_rx]
1197
        inc     dword [device.packets_rx]
1192
 
1198
 
1193
        push    [esi + rx_desc.buf_soft_addr]
1199
        push    [esi + rx_desc.buf_soft_addr]
1194
 
1200
 
1195
;----------------------
1201
;----------------------
1196
; Allocate a new buffer
1202
; Allocate a new buffer
1197
 
1203
 
1198
        stdcall KernelAlloc, RX_BUF_SIZE
1204
        stdcall KernelAlloc, RX_BUF_SIZE
1199
        mov     [esi + rx_desc.buf_soft_addr], eax
1205
        mov     [esi + rx_desc.buf_soft_addr], eax
1200
        GetRealAddr
1206
        GetRealAddr
1201
        mov     dword [esi + rx_desc.buf_addr], eax
1207
        mov     dword [esi + rx_desc.buf_addr], eax
1202
 
1208
 
1203
;---------------
1209
;---------------
1204
; re set OWN bit
1210
; re set OWN bit
1205
 
1211
 
1206
        mov     eax, DSB_OWNbit or RX_BUF_SIZE
1212
        mov     eax, DSB_OWNbit or RX_BUF_SIZE
1207
        cmp     [tpc.cur_rx], NUM_RX_DESC - 1
1213
        cmp     [tpc.cur_rx], NUM_RX_DESC - 1
1208
        jne     @f
1214
        jne     @f
1209
        or      eax, DSB_EORbit
1215
        or      eax, DSB_EORbit
1210
    @@: mov     [esi + rx_desc.status], eax
1216
    @@: mov     [esi + rx_desc.status], eax
1211
 
1217
 
1212
;--------------
1218
;--------------
1213
; Update rx ptr
1219
; Update rx ptr
1214
 
1220
 
1215
        inc     [tpc.cur_rx]
1221
        inc     [tpc.cur_rx]
1216
        and     [tpc.cur_rx], NUM_RX_DESC - 1
1222
        and     [tpc.cur_rx], NUM_RX_DESC - 1
1217
 
1223
 
1218
        jmp     Eth_input
1224
        jmp     Eth_input
1219
  .rx_return:
1225
  .rx_return:
1220
 
1226
 
1221
        pop     ax
1227
        pop     ax
1222
  .no_rx:
1228
  .no_rx:
1223
 
1229
 
1224
;---------
1230
;---------
1225
; Transmit
1231
; Transmit
1226
 
1232
 
1227
        test    ax, ISB_TxOK
1233
        test    ax, ISB_TxOK
1228
        jz      .no_tx
1234
        jz      .no_tx
1229
        push    ax
1235
        push    ax
1230
 
1236
 
1231
        DEBUGF  1,"TX ok!\n"
1237
        DEBUGF  1,"TX ok!\n"
1232
 
1238
 
1233
        mov     ecx, NUM_TX_DESC
1239
        mov     ecx, NUM_TX_DESC
1234
        lea     esi, [device.tx_ring]
1240
        lea     esi, [device.tx_ring]
1235
  .txloop:
1241
  .txloop:
1236
        cmp     [esi + tx_desc.buf_soft_addr], 0
1242
        cmp     [esi + tx_desc.buf_soft_addr], 0
1237
        jz      .maybenext
1243
        jz      .maybenext
1238
 
1244
 
1239
        test    [esi + tx_desc.status], DSB_OWNbit
1245
        test    [esi + tx_desc.status], DSB_OWNbit
1240
        jnz     .maybenext
1246
        jnz     .maybenext
1241
 
1247
 
1242
        push    ecx
1248
        push    ecx
1243
        DEBUGF  1,"Freeing up TX desc: %x\n", esi
1249
        DEBUGF  1,"Freeing up TX desc: %x\n", esi
1244
        stdcall KernelFree, [esi + tx_desc.buf_soft_addr]
1250
        stdcall KernelFree, [esi + tx_desc.buf_soft_addr]
1245
        pop     ecx
1251
        pop     ecx
1246
        and     [esi + tx_desc.buf_soft_addr], 0
1252
        and     [esi + tx_desc.buf_soft_addr], 0
1247
 
1253
 
1248
  .maybenext:
1254
  .maybenext:
1249
        add     esi, tx_desc.size
1255
        add     esi, tx_desc.size
1250
        dec     ecx
1256
        dec     ecx
1251
        jnz     .txloop
1257
        jnz     .txloop
1252
 
1258
 
1253
        pop     ax
1259
        pop     ax
1254
  .no_tx:
1260
  .no_tx:
1255
 
1261
 
1256
;-------
1262
;-------
1257
; Finish
1263
; Finish
1258
 
1264
 
1259
        set_io  0
1265
        set_io  0
1260
        set_io  REG_IntrStatus
1266
        set_io  REG_IntrStatus
1261
        out     dx, ax                  ; ACK all interrupts
1267
        out     dx, ax                  ; ACK all interrupts
1262
 
1268
 
1263
  .fail:
1269
  .fail:
1264
        pop     edi esi ebx
1270
        pop     edi esi ebx
1265
        xor     eax, eax
1271
        xor     eax, eax
1266
        inc     eax
1272
        inc     eax
1267
 
1273
 
1268
        ret
1274
        ret
1269
 
1275
 
1270
 
1276
 
1271
 
1277
 
1272
 
1278
 
1273
 
1279
 
1274
 
1280
 
1275
 
1281
 
1276
 
1282
 
1277
 
1283
 
1278
; End of code
1284
; End of code
1279
align 4                                         ; Place all initialised data here
1285
align 4                                         ; Place all initialised data here
1280
 
1286
 
1281
devices       dd 0
1287
devices       dd 0
1282
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1288
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1283
my_service    db 'RTL8169',0                    ; max 16 chars include zero
1289
my_service    db 'RTL8169',0                    ; max 16 chars include zero
1284
 
1290
 
1285
include_debug_strings                           ; All data wich FDO uses will be included here
1291
include_debug_strings                           ; All data wich FDO uses will be included here
1286
 
1292
 
1287
rtl_chip_info dd \
1293
rtl_chip_info dd \
1288
  MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169
1294
  MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169
1289
  MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s
1295
  MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s
1290
  MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s
1296
  MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s
1291
  MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb
1297
  MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb
1292
  MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc
1298
  MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc
1293
  MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
1299
  MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
1294
  MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
1300
  MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
1295
  MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e         // PCI-E 8139
1301
  MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e         // PCI-E 8139
1296
  MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e         // PCI-E 8139
1302
  MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e         // PCI-E 8139
1297
  MCFG_METHOD_15, 0xff7e1880    ; RTL8100e         // PCI-E 8139
1303
  MCFG_METHOD_15, 0xff7e1880    ; RTL8100e         // PCI-E 8139
1298
 
1304
 
1299
mac_info dd \
1305
mac_info dd \
1300
  0x38800000, MCFG_METHOD_15, \
1306
  0x38800000, MCFG_METHOD_15, \
1301
  0x38000000, MCFG_METHOD_12, \
1307
  0x38000000, MCFG_METHOD_12, \
1302
  0x34000000, MCFG_METHOD_13, \
1308
  0x34000000, MCFG_METHOD_13, \
1303
  0x30800000, MCFG_METHOD_14, \
1309
  0x30800000, MCFG_METHOD_14, \
1304
  0x30000000, MCFG_METHOD_11, \
1310
  0x30000000, MCFG_METHOD_11, \
1305
  0x18000000, MCFG_METHOD_05, \
1311
  0x18000000, MCFG_METHOD_05, \
1306
  0x10000000, MCFG_METHOD_04, \
1312
  0x10000000, MCFG_METHOD_04, \
1307
  0x04000000, MCFG_METHOD_03, \
1313
  0x04000000, MCFG_METHOD_03, \
1308
  0x00800000, MCFG_METHOD_02, \
1314
  0x00800000, MCFG_METHOD_02, \
1309
  0x00000000, MCFG_METHOD_01    ; catch-all
1315
  0x00000000, MCFG_METHOD_01    ; catch-all
1310
 
1316
 
1311
name_01         db "RTL8169", 0
1317
name_01         db "RTL8169", 0
1312
name_02_03      db "RTL8169s/8110s", 0
1318
name_02_03      db "RTL8169s/8110s", 0
1313
name_04         db "RTL8169sb/8110sb", 0
1319
name_04         db "RTL8169sb/8110sb", 0
1314
name_05         db "RTL8169sc/8110sc", 0
1320
name_05         db "RTL8169sc/8110sc", 0
1315
name_11_12      db "RTL8168b/8111b", 0  ; PCI-E
1321
name_11_12      db "RTL8168b/8111b", 0  ; PCI-E
1316
name_13         db "RTL8101e", 0        ; PCI-E 8139
1322
name_13         db "RTL8101e", 0        ; PCI-E 8139
1317
name_14_15      db "RTL8100e", 0        ; PCI-E 8139
1323
name_14_15      db "RTL8100e", 0        ; PCI-E 8139
1318
 
1324
 
1319
 
1325
 
1320
section '.data' data readable writable align 16 ; place all uninitialized data place here
1326
section '.data' data readable writable align 16 ; place all uninitialized data place here
1321
 
1327
 
1322
device_list rd MAX_DEVICES                     ; This list contains all pointers to device structures the driver is handling
1328
device_list rd MAX_DEVICES                     ; This list contains all pointers to device structures the driver is handling