Subversion Repositories Kolibri OS

Rev

Rev 9148 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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