Subversion Repositories Kolibri OS

Rev

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

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