Subversion Repositories Kolibri OS

Rev

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

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