Subversion Repositories Kolibri OS

Rev

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

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