Subversion Repositories Kolibri OS

Rev

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

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