Subversion Repositories Kolibri OS

Rev

Rev 425 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
425 victor 1
$Revision: 431 $
373 mikedld 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;                                                                 ;;
431 serge 4
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved.    ;;
5
;; Distributed under terms of the GNU General Public License       ;;
6
;;                                                                 ;;
373 mikedld 7
;;  RTL8169.INC                                                    ;;
8
;;                                                                 ;;
9
;;  Ethernet driver for Menuet OS                                  ;;
10
;;                                                                 ;;
11
;;  Version 0.1  11 February 2007                                  ;;
12
;;                                                                 ;;
13
;;  Driver for chips of RealTek 8169 family                        ;;
14
;;  References:                                                    ;;
15
;;    r8169.c - linux driver (etherboot project)                   ;;
16
;;    ethernet driver template by Mike Hibbett                     ;;
17
;;                                                                 ;;
18
;;  The copyright statement is                                     ;;
19
;;                                                                 ;;
20
;;          GNU GENERAL PUBLIC LICENSE                             ;;
21
;;             Version 2, June 1991                                ;;
22
;;                                                                 ;;
23
;;  Copyright 2007 mike.dld,                                       ;;
24
;;   mike.dld@gmail.com                                            ;;
25
;;                                                                 ;;
26
;;  See file COPYING for details                                   ;;
27
;;                                                                 ;;
28
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29
 
30
	ETH_ALEN	       equ 6
31
	ETH_HLEN	       equ (2 * ETH_ALEN + 2)
32
	ETH_ZLEN	       equ 60 ; 60 + 4bytes auto payload for
33
				      ; mininmum 64bytes frame length
34
 
35
	RTL8169_REG_MAC0	       equ 0x0 ; Ethernet hardware address
36
	RTL8169_REG_MAR0	       equ 0x8 ; Multicast filter
37
	RTL8169_REG_TxDescStartAddr    equ 0x20
38
	RTL8169_REG_TxHDescStartAddr   equ 0x28
39
	RTL8169_REG_FLASH	       equ 0x30
40
	RTL8169_REG_ERSR	       equ 0x36
41
	RTL8169_REG_ChipCmd	       equ 0x37
42
	RTL8169_REG_TxPoll	       equ 0x38
43
	RTL8169_REG_IntrMask	       equ 0x3C
44
	RTL8169_REG_IntrStatus	       equ 0x3E
45
	RTL8169_REG_TxConfig	       equ 0x40
46
	RTL8169_REG_RxConfig	       equ 0x44
47
	RTL8169_REG_RxMissed	       equ 0x4C
48
	RTL8169_REG_Cfg9346	       equ 0x50
49
	RTL8169_REG_Config0	       equ 0x51
50
	RTL8169_REG_Config1	       equ 0x52
51
	RTL8169_REG_Config2	       equ 0x53
52
	RTL8169_REG_Config3	       equ 0x54
53
	RTL8169_REG_Config4	       equ 0x55
54
	RTL8169_REG_Config5	       equ 0x56
55
	RTL8169_REG_MultiIntr	       equ 0x5C
56
	RTL8169_REG_PHYAR	       equ 0x60
57
	RTL8169_REG_TBICSR	       equ 0x64
58
	RTL8169_REG_TBI_ANAR	       equ 0x68
59
	RTL8169_REG_TBI_LPAR	       equ 0x6A
60
	RTL8169_REG_PHYstatus	       equ 0x6C
61
	RTL8169_REG_RxMaxSize	       equ 0xDA
62
	RTL8169_REG_CPlusCmd	       equ 0xE0
63
	RTL8169_REG_RxDescStartAddr    equ 0xE4
64
	RTL8169_REG_ETThReg	       equ 0xEC
65
	RTL8169_REG_FuncEvent	       equ 0xF0
66
	RTL8169_REG_FuncEventMask      equ 0xF4
67
	RTL8169_REG_FuncPresetState    equ 0xF8
68
	RTL8169_REG_FuncForceEvent     equ 0xFC
69
 
70
	; InterruptStatusBits
71
	RTL8169_ISB_SYSErr	       equ 0x8000
72
	RTL8169_ISB_PCSTimeout	       equ 0x4000
73
	RTL8169_ISB_SWInt	       equ 0x0100
74
	RTL8169_ISB_TxDescUnavail      equ 0x80
75
	RTL8169_ISB_RxFIFOOver	       equ 0x40
76
	RTL8169_ISB_LinkChg	       equ 0x20
77
	RTL8169_ISB_RxOverflow	       equ 0x10
78
	RTL8169_ISB_TxErr	       equ 0x08
79
	RTL8169_ISB_TxOK	       equ 0x04
80
	RTL8169_ISB_RxErr	       equ 0x02
81
	RTL8169_ISB_RxOK	       equ 0x01
82
 
83
	; RxStatusDesc
84
	RTL8169_SD_RxRES	       equ 0x00200000
85
	RTL8169_SD_RxCRC	       equ 0x00080000
86
	RTL8169_SD_RxRUNT	       equ 0x00100000
87
	RTL8169_SD_RxRWT	       equ 0x00400000
88
 
89
	; ChipCmdBits
90
	RTL8169_CMD_Reset	       equ 0x10
91
	RTL8169_CMD_RxEnb	       equ 0x08
92
	RTL8169_CMD_TxEnb	       equ 0x04
93
	RTL8169_CMD_RxBufEmpty	       equ 0x01
94
 
95
	; Cfg9346Bits
96
	RTL8169_CFG_9346_Lock	       equ 0x00
97
	RTL8169_CFG_9346_Unlock        equ 0xC0
98
 
99
	; rx_mode_bits
100
	RTL8169_RXM_AcceptErr	       equ 0x20
101
	RTL8169_RXM_AcceptRunt	       equ 0x10
102
	RTL8169_RXM_AcceptBroadcast    equ 0x08
103
	RTL8169_RXM_AcceptMulticast    equ 0x04
104
	RTL8169_RXM_AcceptMyPhys       equ 0x02
105
	RTL8169_RXM_AcceptAllPhys      equ 0x01
106
 
107
	; RxConfigBits
108
	RTL8169_RXC_FIFOShift	       equ 13
109
	RTL8169_RXC_DMAShift	       equ 8
110
 
111
	; TxConfigBits
112
	RTL8169_TXC_InterFrameGapShift equ 24
113
	RTL8169_TXC_DMAShift	       equ 8	; DMA burst value (0-7) is shift this many bits
114
 
115
	; rtl8169_PHYstatus
116
	RTL8169_PHYS_TBI_Enable        equ 0x80
117
	RTL8169_PHYS_TxFlowCtrl        equ 0x40
118
	RTL8169_PHYS_RxFlowCtrl        equ 0x20
119
	RTL8169_PHYS_1000bpsF	       equ 0x10
120
	RTL8169_PHYS_100bps	       equ 0x08
121
	RTL8169_PHYS_10bps	       equ 0x04
122
	RTL8169_PHYS_LinkStatus        equ 0x02
123
	RTL8169_PHYS_FullDup	       equ 0x01
124
 
125
	; GIGABIT_PHY_registers
126
	RTL8169_PHY_CTRL_REG	       equ 0
127
	RTL8169_PHY_STAT_REG	       equ 1
128
	RTL8169_PHY_AUTO_NEGO_REG      equ 4
129
	RTL8169_PHY_1000_CTRL_REG      equ 9
130
 
131
	; GIGABIT_PHY_REG_BIT
132
	RTL8169_PHY_Restart_Auto_Nego  equ 0x0200
133
	RTL8169_PHY_Enable_Auto_Nego   equ 0x1000
134
 
135
	; PHY_STAT_REG = 1;
136
	RTL8169_PHY_Auto_Neco_Comp     equ 0x0020
137
 
138
	; PHY_AUTO_NEGO_REG = 4;
139
	RTL8169_PHY_Cap_10_Half        equ 0x0020
140
	RTL8169_PHY_Cap_10_Full        equ 0x0040
141
	RTL8169_PHY_Cap_100_Half       equ 0x0080
142
	RTL8169_PHY_Cap_100_Full       equ 0x0100
143
 
144
	; PHY_1000_CTRL_REG = 9;
145
	RTL8169_PHY_Cap_1000_Full      equ 0x0200
146
	RTL8169_PHY_Cap_1000_Half      equ 0x0100
147
 
148
	RTL8169_PHY_Cap_PAUSE	       equ 0x0400
149
	RTL8169_PHY_Cap_ASYM_PAUSE     equ 0x0800
150
 
151
	RTL8169_PHY_Cap_Null	       equ 0x0
152
 
153
	; _MediaType
154
	RTL8169_MT_10_Half	       equ 0x01
155
	RTL8169_MT_10_Full	       equ 0x02
156
	RTL8169_MT_100_Half	       equ 0x04
157
	RTL8169_MT_100_Full	       equ 0x08
158
	RTL8169_MT_1000_Full	       equ 0x10
159
 
160
	; _TBICSRBit
161
	RTL8169_TBI_LinkOK	       equ 0x02000000
162
 
163
	; _DescStatusBit
164
	RTL8169_DSB_OWNbit	       equ 0x80000000
165
	RTL8169_DSB_EORbit	       equ 0x40000000
166
	RTL8169_DSB_FSbit	       equ 0x20000000
167
	RTL8169_DSB_LSbit	       equ 0x10000000
168
 
169
; MAC address length
170
MAC_ADDR_LEN	    equ 6
171
 
172
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
173
MAX_ETH_FRAME_SIZE  equ 1536
174
 
175
TX_FIFO_THRESH	    equ 256	; In bytes
176
 
177
RX_FIFO_THRESH	    equ 7	; 7 means NO threshold, Rx buffer level before first PCI xfer
178
RX_DMA_BURST	    equ 7	; Maximum PCI burst, '6' is 1024
179
TX_DMA_BURST	    equ 7	; Maximum PCI burst, '6' is 1024
180
ETTh		    equ 0x3F	; 0x3F means NO threshold
181
 
182
EarlyTxThld	    equ 0x3F	; 0x3F means NO early transmit
183
RxPacketMaxSize     equ 0x0800	; Maximum size supported is 16K-1
184
InterFrameGap	    equ 0x03	; 3 means InterFrameGap = the shortest one
185
 
186
NUM_TX_DESC	    equ 1	; Number of Tx descriptor registers
187
NUM_RX_DESC	    equ 4	; Number of Rx descriptor registers
188
RX_BUF_SIZE	    equ 1536	; Rx Buffer size
189
 
190
HZ		    equ 1000
191
 
192
RTL_MIN_IO_SIZE     equ 0x80
193
TX_TIMEOUT	    equ (6*HZ)
194
 
195
RTL8169_TIMER_EXPIRE_TIME equ 100
196
 
197
ETH_HDR_LEN	    equ 14
198
DEFAULT_MTU	    equ 1500
199
DEFAULT_RX_BUF_LEN  equ 1536
200
 
201
 
202
;#ifdef RTL8169_JUMBO_FRAME_SUPPORT
203
;#define MAX_JUMBO_FRAME_MTU    ( 10000 )
204
;#define MAX_RX_SKBDATA_SIZE    ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN )
205
;#else
206
MAX_RX_SKBDATA_SIZE equ 1600
207
;#endif                         //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT
208
 
209
;#ifdef RTL8169_USE_IO
210
;!!!#define RTL_W8(reg, val8)   outb ((val8), ioaddr + (reg))
211
macro RTL_W8 reg,val8 {
212
  if ~reg eq dx
213
    mov dx,word[rtl8169_tpc.mmio_addr]
214
    add dx,reg
215
  end if
216
  if ~val8 eq al
217
    mov al,val8
218
  end if
219
  out dx,al
220
}
221
;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg))
222
macro RTL_W16 reg,val16 {
223
  if ~reg eq dx
224
    mov dx,word[rtl8169_tpc.mmio_addr]
225
    add dx,reg
226
  end if
227
  if ~val16 eq ax
228
    mov ax,val16
229
  end if
230
  out dx,ax
231
}
232
;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg))
233
macro RTL_W32 reg,val32 {
234
  if ~reg eq dx
235
    mov dx,word[rtl8169_tpc.mmio_addr]
236
    add dx,reg
237
  end if
238
  if ~val32 eq eax
239
    mov eax,val32
240
  end if
241
  out dx,eax
242
}
243
;!!!#define RTL_R8(reg)         inb (ioaddr + (reg))
244
macro RTL_R8 reg {
245
  if ~reg eq dx
246
    mov dx,word[rtl8169_tpc.mmio_addr]
247
    add dx,reg
248
  end if
249
  in  al,dx
250
}
251
;!!!#define RTL_R16(reg)        inw (ioaddr + (reg))
252
macro RTL_R16 reg {
253
  if ~reg eq dx
254
    mov dx,word[rtl8169_tpc.mmio_addr]
255
    add dx,reg
256
  end if
257
  in  ax,dx
258
}
259
;!!!#define RTL_R32(reg)        ((unsigned long) inl (ioaddr + (reg)))
260
macro RTL_R32 reg {
261
  if ~reg eq dx
262
    mov dx,word[rtl8169_tpc.mmio_addr]
263
    add dx,reg
264
  end if
265
  in  eax,dx
266
}
267
;#else
268
; write/read MMIO register
269
;#define RTL_W8(reg, val8)      writeb ((val8), ioaddr + (reg))
270
;#define RTL_W16(reg, val16)    writew ((val16), ioaddr + (reg))
271
;#define RTL_W32(reg, val32)    writel ((val32), ioaddr + (reg))
272
;#define RTL_R8(reg)            readb (ioaddr + (reg))
273
;#define RTL_R16(reg)           readw (ioaddr + (reg))
274
;#define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
275
;#endif
276
 
277
MCFG_METHOD_01	     equ 0x01
278
MCFG_METHOD_02	     equ 0x02
279
MCFG_METHOD_03	     equ 0x03
280
MCFG_METHOD_04	     equ 0x04
281
MCFG_METHOD_05	     equ 0x05
282
MCFG_METHOD_11	     equ 0x0b
283
MCFG_METHOD_12	     equ 0x0c
284
MCFG_METHOD_13	     equ 0x0d
285
MCFG_METHOD_14	     equ 0x0e
286
MCFG_METHOD_15	     equ 0x0f
287
 
288
PCFG_METHOD_1	    equ 0x01	; PHY Reg 0x03 bit0-3 == 0x0000
289
PCFG_METHOD_2	    equ 0x02	; PHY Reg 0x03 bit0-3 == 0x0001
290
PCFG_METHOD_3	    equ 0x03	; PHY Reg 0x03 bit0-3 == 0x0002
291
 
292
PCI_COMMAND_IO		equ 0x1   ; Enable response in I/O space
293
PCI_COMMAND_MEM 	equ 0x2   ; Enable response in mem space
294
PCI_COMMAND_MASTER	equ 0x4   ; Enable bus mastering
295
PCI_LATENCY_TIMER	equ 0x0d  ; 8 bits
296
PCI_COMMAND_SPECIAL	equ 0x8   ; Enable response to special cycles
297
PCI_COMMAND_INVALIDATE	equ 0x10  ; Use memory write and invalidate
298
PCI_COMMAND_VGA_PALETTE equ 0x20  ; Enable palette snooping
299
PCI_COMMAND_PARITY	equ 0x40  ; Enable parity checking
300
PCI_COMMAND_WAIT	equ 0x80  ; Enable address/data stepping
301
PCI_COMMAND_SERR	equ 0x100 ; Enable SERR
302
PCI_COMMAND_FAST_BACK	equ 0x200 ; Enable back-to-back writes
303
 
304
struc rtl8169_TxDesc {
305
  .status    dd ?
306
  .vlan_tag  dd ?
307
  .buf_addr  dd ?
308
  .buf_Haddr dd ?
309
}
310
virtual at 0
311
  rtl8169_TxDesc rtl8169_TxDesc
312
  sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc
313
end virtual
314
 
315
struc rtl8169_RxDesc {
316
  .status    dd ?
317
  .vlan_tag  dd ?
318
  .buf_addr  dd ?
319
  .buf_Haddr dd ?
320
}
321
virtual at 0
322
  rtl8169_RxDesc rtl8169_RxDesc
323
  sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc
324
end virtual
325
 
326
virtual at eth_data_start
327
 
328
; Define the TX Descriptor
329
align 256
330
rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc
331
 
332
; Create a static buffer of size RX_BUF_SZ for each
333
; TX Descriptor.  All descriptors point to a
334
; part of this buffer
335
align 256
336
rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE
337
 
338
; Define the RX Descriptor
339
align 256
340
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc
341
 
342
; Create a static buffer of size RX_BUF_SZ for each
343
; RX Descriptor   All descriptors point to a
344
; part of this buffer
345
align 256
346
rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE
347
 
348
rtl8169_tpc:
349
  .mmio_addr	dd ? ; memory map physical address
350
  .chipset	dd ?
351
  .pcfg 	dd ?
352
  .mcfg 	dd ?
353
  .cur_rx	dd ? ; Index into the Rx descriptor buffer of next Rx pkt
354
  .cur_tx	dd ? ; Index into the Tx descriptor buffer of next Rx pkt
355
  .TxDescArrays dd ? ; Index of Tx Descriptor buffer
356
  .RxDescArrays dd ? ; Index of Rx Descriptor buffer
357
  .TxDescArray	dd ? ; Index of 256-alignment Tx Descriptor buffer
358
  .RxDescArray	dd ? ; Index of 256-alignment Rx Descriptor buffer
359
  .RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array
360
  .Tx_skbuff	rd NUM_TX_DESC
361
 
362
end virtual
363
 
364
rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK
365
rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E
366
 
367
iglobal
368
 
369
;static struct {
370
;       const char *name;
371
;       u8 mcfg;                /* depend on RTL8169 docs */
372
;       u32 RxConfigMask;       /* should clear the bits supported by this chip */
373
;}
374
rtl_chip_info dd \
375
  MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169
376
  MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s
377
  MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s
378
  MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb
379
  MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc
380
  MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
381
  MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b   // PCI-E
382
  MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e         // PCI-E 8139
383
  MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e         // PCI-E 8139
384
  MCFG_METHOD_15, 0xff7e1880	; RTL8100e         // PCI-E 8139
385
 
386
mac_info dd \
387
  0x38800000, MCFG_METHOD_15, \
388
  0x38000000, MCFG_METHOD_12, \
389
  0x34000000, MCFG_METHOD_13, \
390
  0x30800000, MCFG_METHOD_14, \
391
  0x30000000, MCFG_METHOD_11, \
392
  0x18000000, MCFG_METHOD_05, \
393
  0x10000000, MCFG_METHOD_04, \
394
  0x04000000, MCFG_METHOD_03, \
395
  0x00800000, MCFG_METHOD_02, \
396
  0x00000000, MCFG_METHOD_01	; catch-all
397
 
398
endg
399
 
400
PCI_COMMAND_IO		equ 0x1    ; Enable response in I/O space
401
PCI_COMMAND_MEM 	equ 0x2    ; Enable response in mem space
402
PCI_COMMAND_MASTER	equ 0x4    ; Enable bus mastering
403
PCI_LATENCY_TIMER	equ 0x0d   ; 8 bits
404
PCI_COMMAND_SPECIAL	equ 0x8    ; Enable response to special cycles
405
PCI_COMMAND_INVALIDATE	equ 0x10   ; Use memory write and invalidate
406
PCI_COMMAND_VGA_PALETTE equ 0x20   ; Enable palette snooping
407
PCI_COMMAND_PARITY	equ 0x40   ; Enable parity checking
408
PCI_COMMAND_WAIT	equ 0x80   ; Enable address/data stepping
409
PCI_COMMAND_SERR	equ 0x100  ; Enable SERR
410
PCI_COMMAND_FAST_BACK	equ 0x200  ; Enable back-to-back writes
411
 
412
PCI_VENDOR_ID		equ 0x00   ; 16 bits
413
PCI_DEVICE_ID		equ 0x02   ; 16 bits
414
PCI_COMMAND		equ 0x04   ; 16 bits
415
 
416
PCI_BASE_ADDRESS_0	equ 0x10   ; 32 bits
417
PCI_BASE_ADDRESS_1	equ 0x14   ; 32 bits
418
PCI_BASE_ADDRESS_2	equ 0x18   ; 32 bits
419
PCI_BASE_ADDRESS_3	equ 0x1c   ; 32 bits
420
PCI_BASE_ADDRESS_4	equ 0x20   ; 32 bits
421
PCI_BASE_ADDRESS_5	equ 0x24   ; 32 bits
422
 
423
PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06
424
PCI_BASE_ADDRESS_MEM_TYPE_32   equ 0x00 ; 32 bit address
425
PCI_BASE_ADDRESS_MEM_TYPE_1M   equ 0x02 ; Below 1M [obsolete]
426
PCI_BASE_ADDRESS_MEM_TYPE_64   equ 0x04 ; 64 bit address
427
 
428
PCI_BASE_ADDRESS_IO_MASK  equ (not 0x03)
429
PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f)
430
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
431
PCI_ROM_ADDRESS 	  equ 0x30	; 32 bits
432
 
433
proc CONFIG_CMD,where:byte
434
	movzx	eax,byte[pci_bus]
435
	shl	eax,8
436
	mov	al,[pci_dev]
437
	shl	eax,8
438
	mov	al,[where]
439
	and	al,not 3
440
	or	eax,0x80000000
441
	ret
442
endp
443
 
444
proc pci_read_config_byte,where:dword
445
	push	edx
446
	stdcall CONFIG_CMD,[where]
447
	mov	dx,0xCF8
448
	out	dx,eax
449
	mov	edx,[where]
450
	and	edx,3
451
	add	edx,0xCFC
452
	in	al,dx
453
	pop	edx
454
	ret
455
endp
456
 
457
proc pci_read_config_word,where:dword
458
	push	edx
459
	stdcall CONFIG_CMD,[where]
460
	mov	dx,0xCF8
461
	out	dx,eax
462
	mov	edx,[where]
463
	and	edx,2
464
	add	edx,0xCFC
465
	in	ax,dx
466
	pop	edx
467
	ret
468
endp
469
 
470
proc pci_read_config_dword,where:dword
471
	push	edx
472
	stdcall CONFIG_CMD,[where]
473
	mov	edx,0xCF8
474
	out	dx,eax
475
	mov	edx,0xCFC
476
	in	eax,dx
477
	pop	edx
478
	ret
479
endp
480
 
481
proc pci_write_config_byte,where:dword,value:byte
482
	push	edx
483
	stdcall CONFIG_CMD,[where]
484
	mov	dx,0xCF8
485
	out	dx,eax
486
	mov	edx,[where]
487
	and	edx,3
488
	add	edx,0xCFC
489
	mov	al,[value]
490
	out	dx,al
491
	pop	edx
492
	ret
493
endp
494
 
495
proc pci_write_config_word,where:dword,value:word
496
	push	edx
497
	stdcall CONFIG_CMD,[where]
498
	mov	dx,0xCF8
499
	out	dx,eax
500
	mov	edx,[where]
501
	and	edx,2
502
	add	edx,0xCFC
503
	mov	ax,[value]
504
	out	dx,ax
505
	pop	edx
506
	ret
507
endp
508
 
509
proc pci_write_config_dword,where:dword,value:dword
510
	push	edx
511
	stdcall CONFIG_CMD,[where]
512
	mov	edx,0xCF8
513
	out	dx,eax
514
	mov	edx,0xCFC
515
	mov	eax,[value]
516
	out	dx,eax
517
	pop	edx
518
	ret
519
endp
520
 
521
; Set device to be a busmaster in case BIOS neglected to do so.
522
; Also adjust PCI latency timer to a reasonable value, 32.
523
proc adjust_pci_device
524
 
525
	DEBUGF	1,"K : adjust_pci_device\n"
526
 
527
	stdcall pci_read_config_word,PCI_COMMAND
528
	mov	bx,ax
529
	or	bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO
530
	cmp	ax,bx
531
	je	@f
532
	DEBUGF	1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK :   Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2
533
	stdcall pci_write_config_word,PCI_COMMAND,ebx
534
    @@:
535
	stdcall pci_read_config_byte,PCI_LATENCY_TIMER
536
	cmp	al,32
537
	jae	@f
538
	DEBUGF	1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK :   Setting to 32 clocks.\n",al
539
	stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32
540
    @@:
541
	ret
542
endp
543
 
544
; Find the start of a pci resource
545
proc pci_bar_start,index:dword
546
	stdcall pci_read_config_dword,[index]
547
	test	eax,PCI_BASE_ADDRESS_SPACE_IO
548
	jz	@f
549
	and	eax,PCI_BASE_ADDRESS_IO_MASK
550
	jmp	.exit
551
    @@: push	eax
552
	and	eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK
553
	cmp	eax,PCI_BASE_ADDRESS_MEM_TYPE_64
554
	jne	.not64
555
	mov	eax,[index]
556
	add	eax,4
557
	stdcall pci_read_config_dword,eax
558
	or	eax,eax
559
	jz	.not64
560
	DEBUGF	1,"K : pci_bar_start: Unhandled 64bit BAR\n"
561
	add	esp,4
562
	or	eax,-1
563
	ret
564
  .not64:
565
	pop	eax
566
	and	eax,PCI_BASE_ADDRESS_MEM_MASK
567
  .exit:
568
	ret
569
endp
570
 
571
proc rtl8169_init_board
572
 
573
	DEBUGF	1,"K : rtl8169_init_board\n"
574
 
575
	call	adjust_pci_device
576
 
577
	stdcall pci_bar_start,PCI_BASE_ADDRESS_0
578
	mov	[rtl8169_tpc.mmio_addr],eax
579
	; Soft reset the chip
580
	RTL_W8	RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
581
 
582
	; Check that the chip has finished the reset
583
	mov	ecx,1000
584
    @@: RTL_R8	RTL8169_REG_ChipCmd
585
	test	al,RTL8169_CMD_Reset
586
	jz	@f
587
	stdcall udelay,10
588
	loop	@b
589
    @@:
590
	; identify config method
591
	RTL_R32 RTL8169_REG_TxConfig
592
	and	eax,0x7c800000
593
	DEBUGF	1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax
594
	mov	esi,mac_info-8
595
    @@: add	esi,8
596
	mov	ecx,eax
597
	and	ecx,[esi]
598
	cmp	ecx,[esi]
599
	jne	@b
600
	mov	eax,[esi+4]
601
	mov	[rtl8169_tpc.mcfg],eax
602
 
603
	mov	[rtl8169_tpc.pcfg],PCFG_METHOD_3
604
	stdcall RTL8169_READ_GMII_REG,3
605
	and	al,0x0f
606
	or	al,al
607
	jnz	@f
608
	mov	[rtl8169_tpc.pcfg],PCFG_METHOD_1
609
	jmp	.pconf
610
    @@: dec	al
611
	jnz	.pconf
612
	mov	[rtl8169_tpc.pcfg],PCFG_METHOD_2
613
  .pconf:
614
 
615
	; identify chip attached to board
616
	mov	ecx,10
617
	mov	eax,[rtl8169_tpc.mcfg]
618
    @@: dec	ecx
619
	js	@f
620
	cmp	eax,[rtl_chip_info+ecx*8]
621
	jne	@b
622
	mov	[rtl8169_tpc.chipset],ecx
623
	jmp	.match
624
    @@:
625
	; if unknown chip, assume array element #0, original RTL-8169 in this case
626
	DEBUGF	1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n"
627
	RTL_R32 RTL8169_REG_TxConfig
628
	DEBUGF	1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax
629
 
630
	mov	[rtl8169_tpc.chipset],0
631
 
632
	xor	eax,eax
633
	inc	eax
634
	ret
635
 
636
  .match:
637
	xor	eax,eax
638
	ret
639
endp
640
 
641
proc rtl8169_hw_PHY_config
642
 
643
	DEBUGF	1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg]
644
 
645
;       DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg);
646
 
647
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_04
648
	jne	.not_4
649
;       stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
650
;       stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e
651
;       stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb
652
;       stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a
653
	stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002
654
	stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0
655
	stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000
656
	jmp	.exit
657
  .not_4:
658
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_02
659
	je	@f
660
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_03
661
	jne	.not_2_or_3
662
    @@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
663
	stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000
664
	stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7
665
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
666
	stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1
667
	stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008
668
	stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020
669
	stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000
670
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800
671
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
672
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000
673
	stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41
674
	stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60
675
	stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140
676
	stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077
677
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800
678
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000
679
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000
680
	stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01
681
	stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20
682
	stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95
683
	stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00
684
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800
685
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000
686
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000
687
	stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41
688
	stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20
689
	stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140
690
	stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB
691
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800
692
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000
693
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000
694
	stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01
695
	stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20
696
	stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95
697
	stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00
698
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800
699
	stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000
700
	stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
701
	stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000
702
	stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000
703
	jmp	.exit
704
  .not_2_or_3:
705
;       DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg);
706
	DEBUGF	1,"K :   tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg]
707
  .exit:
708
	ret
709
endp
710
 
711
;proc pci_write_config_byte
712
;       ret
713
;endp
714
 
715
proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword
716
 
717
	DEBUGF	1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
718
 
719
	movzx	eax,[RegAddr]
720
	shl	eax,16
721
	or	eax,[value]
722
	or	eax,0x80000000
723
	RTL_W32 RTL8169_REG_PHYAR,eax
724
	stdcall udelay,1000
725
 
726
	mov	ecx,2000
727
	; Check if the RTL8169 has completed writing to the specified MII register
728
    @@: RTL_R32 RTL8169_REG_PHYAR
729
	test	eax,0x80000000
730
	jz	.exit
731
	stdcall udelay,100
732
	loop	@b
733
  .exit:
734
	ret
735
endp
736
 
737
proc RTL8169_READ_GMII_REG,RegAddr:byte
738
 
739
	DEBUGF	1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
740
 
741
	push	ecx
742
	movzx	eax,[RegAddr]
743
	shl	eax,16
744
;       or      eax,0x0
745
	RTL_W32 RTL8169_REG_PHYAR,eax
746
	stdcall udelay,1000
747
 
748
	mov	ecx,2000
749
	; Check if the RTL8169 has completed retrieving data from the specified MII register
750
    @@: RTL_R32 RTL8169_REG_PHYAR
751
	test	eax,0x80000000
752
	jnz	.exit
753
	stdcall udelay,100
754
	loop	@b
755
 
756
	or	eax,-1
757
	pop	ecx
758
	ret
759
  .exit:
760
	RTL_R32 RTL8169_REG_PHYAR
761
	and	eax,0xFFFF
762
	pop	ecx
763
	ret
764
endp
765
 
766
proc rtl8169_set_rx_mode
767
 
768
	DEBUGF	1,"K : rtl8169_set_rx_mode\n"
769
 
770
	; IFF_ALLMULTI
771
	; Too many to filter perfectly -- accept all multicasts
772
	RTL_R32 RTL8169_REG_RxConfig
773
	mov	ecx,[rtl8169_tpc.chipset]
774
	and	eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
775
	or	eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys)
776
	RTL_W32 RTL8169_REG_RxConfig,eax
777
 
778
	; Multicast hash filter
779
	RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff
780
	RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff
781
	ret
782
endp
783
 
784
proc rtl8169_init_ring
785
 
786
	DEBUGF	1,"K : rtl8169_init_ring\n"
787
 
788
	xor	eax,eax
789
	mov	[rtl8169_tpc.cur_rx],eax
790
	mov	[rtl8169_tpc.cur_tx],eax
791
 
792
	mov	edi,[rtl8169_tpc.TxDescArray]
793
	mov	ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4
794
	cld
795
	rep	stosd
796
	mov	edi,[rtl8169_tpc.RxDescArray]
797
	mov	ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4
798
	rep	stosd
799
 
800
	mov	edi,rtl8169_tpc.Tx_skbuff
801
	mov	eax,rtl8169_txb
802
	mov	ecx,NUM_TX_DESC
803
    @@: stosd
804
	inc	eax	      ; add eax,RX_BUF_SIZE ???
805
	loop	@b
806
 
807
;!!!    for (i = 0; i < NUM_RX_DESC; i++) {
808
;!!!            if (i == (NUM_RX_DESC - 1))
809
;!!!                    tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE;
810
;!!!            else
811
;!!!                    tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE;
812
;!!!            tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
813
;!!!            tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]);
814
;!!!    }
815
	mov	esi,rtl8169_tpc.RxBufferRing
816
	mov	edi,[rtl8169_tpc.RxDescArray]
817
	mov	eax,rtl8169_rxb
818
	mov	ecx,NUM_RX_DESC
819
    @@: mov	[esi],eax
820
	mov	[edi+rtl8169_RxDesc.buf_addr],eax
821
	mov	[edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE
822
	add	esi,4
823
	add	edi,sizeof.rtl8169_RxDesc
824
	add	eax,RX_BUF_SIZE
825
	loop	@b
826
 
827
	or	[edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit
828
 
829
	ret
830
endp
831
 
832
proc rtl8169_hw_start
833
 
834
	DEBUGF	1,"K : rtl8169_hw_start\n"
835
 
836
	; Soft reset the chip
837
	RTL_W8	RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
838
	; Check that the chip has finished the reset
839
	mov	ecx,1000
840
    @@: RTL_R8	RTL8169_REG_ChipCmd
841
	and	al,RTL8169_CMD_Reset
842
	jz	@f
843
	stdcall udelay,10
844
	loop	@b
845
    @@:
846
	RTL_W8	RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock
847
	RTL_W8	RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb
848
	RTL_W8	RTL8169_REG_ETThReg,ETTh
849
	; For gigabit rtl8169
850
	RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize
851
	; Set Rx Config register
852
	RTL_R32 RTL8169_REG_RxConfig
853
	mov	ecx,[rtl8169_tpc.chipset]
854
	and	eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
855
	or	eax,rtl8169_rx_config
856
	RTL_W32 RTL8169_REG_RxConfig,eax
857
	; Set DMA burst size and Interframe Gap Time
858
	RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift)
859
	RTL_R16 RTL8169_REG_CPlusCmd
860
	RTL_W16 RTL8169_REG_CPlusCmd,ax
861
 
862
	RTL_R16 RTL8169_REG_CPlusCmd
863
	or	ax,1 shl 3
864
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_02
865
	jne	@f
866
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_03
867
	jne	@f
868
	or	ax,1 shl 14
869
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
870
	jmp	.set
871
    @@:;DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3\n"
872
  .set: RTL_W16 RTL8169_REG_CPlusCmd,ax
873
 
874
;       RTL_W16 0xE2,0x1517
875
;       RTL_W16 0xE2,0x152a
876
;       RTL_W16 0xE2,0x282a
877
	RTL_W16 0xE2,0x0000
878
 
879
	MOV	[rtl8169_tpc.cur_rx],0
880
	RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray]
881
	RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray]
882
	RTL_W8	RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
883
	stdcall udelay,10
884
	RTL_W32 RTL8169_REG_RxMissed,0
885
	call	rtl8169_set_rx_mode
886
	; no early-rx interrupts
887
	RTL_R16 RTL8169_REG_MultiIntr
888
	and	ax,0xF000
889
	RTL_W16 RTL8169_REG_MultiIntr,ax
890
	RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask
891
	ret
892
endp
893
 
894
proc udelay,msec:dword
895
	push	esi
896
	mov	esi,[msec]
897
	call	delay_ms
898
	pop	esi
899
	ret
900
endp
901
 
902
;***************************************************************************
903
;   Function
904
;      rtl8169_probe
905
;   Description
906
;      Searches for an ethernet card, enables it and clears the rx buffer
907
;      If a card was found, it enables the ethernet -> TCPIP link
908
;   Destroyed registers
909
;      eax, ebx, ecx, edx
910
;
911
;***************************************************************************
912
proc rtl8169_probe
913
 
914
	DEBUGF	1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
915
 
916
	call	rtl8169_init_board
917
 
918
	mov	ecx,MAC_ADDR_LEN
919
	mov	edx,[rtl8169_tpc.mmio_addr]
920
	add	edx,RTL8169_REG_MAC0
921
	xor	ebx,ebx
922
	; Get MAC address. FIXME: read EEPROM
923
    @@: RTL_R8	dx
924
	mov	[node_addr+ebx],al
925
	inc	edx
926
	inc	ebx
927
	loop	@b
928
 
929
	DEBUGF	1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2
930
 
931
	; Config PHY
932
	stdcall rtl8169_hw_PHY_config
933
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
934
	RTL_W8	0x82,0x01
935
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_03
936
	jae	@f
937
;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
938
;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
939
   @@:
940
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_02
941
	jne	@f
942
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
943
	RTL_W8	0x82,0x01
944
;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
945
	stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000	; w 0x0b 15 0 0
946
    @@:
947
	; if TBI is not enabled
948
	RTL_R8	RTL8169_REG_PHYstatus
949
	test	al,RTL8169_PHYS_TBI_Enable
950
	jz	.tbi_dis
951
	stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG
952
	; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
953
	and	eax,0x0C1F
954
	or	eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full
955
	stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax
956
	; enable 1000 Full Mode
957
	stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168
958
	; Enable auto-negotiation and restart auto-nigotiation
959
	stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego
960
	stdcall udelay,100
961
	mov	ecx,10000
962
	; wait for auto-negotiation process
963
    @@: dec	ecx
964
	jz	@f
965
	stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG
966
	stdcall udelay,100
967
	test	eax,RTL8169_PHY_Auto_Neco_Comp
968
	jz	@b
969
	RTL_R8	RTL8169_REG_PHYstatus
970
	jmp	@f
971
  .tbi_dis:
972
	stdcall udelay,100
973
    @@:
974
	call	rtl8169_reset
975
	ret
976
endp
977
 
978
;***************************************************************************
979
;   Function
980
;      rt8169_reset
981
;   Description
982
;      Place the chip (ie, the ethernet card) into a virgin state
983
;   Destroyed registers
984
;      eax, ebx, ecx, edx
985
;
986
;***************************************************************************
987
proc rtl8169_reset
988
 
989
	DEBUGF	1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
990
 
991
	mov	[rtl8169_tpc.TxDescArrays],rtl8169_tx_ring
992
	; Tx Desscriptor needs 256 bytes alignment
993
	mov	[rtl8169_tpc.TxDescArray],rtl8169_tx_ring
994
 
995
	mov	[rtl8169_tpc.RxDescArrays],rtl8169_rx_ring
996
	; Rx Desscriptor needs 256 bytes alignment
997
	mov	[rtl8169_tpc.RxDescArray],rtl8169_rx_ring
998
 
999
	call	rtl8169_init_ring
1000
	call	rtl8169_hw_start
1001
	; Construct a perfect filter frame with the mac address as first match
1002
	; and broadcast for all others
1003
	mov	edi,rtl8169_txb
1004
	or	al,-1
1005
	mov	ecx,192
1006
	cld
1007
	rep	stosb
1008
 
1009
	mov	esi,node_addr
1010
	mov	edi,rtl8169_txb
1011
	movsd
1012
	movsw
1013
 
1014
	mov	eax,[pci_data]
1015
	mov	[eth_status],eax
1016
	ret
1017
endp
1018
 
1019
;***************************************************************************
1020
;   Function
1021
;      rtl8169_transmit
1022
;   Description
1023
;      Transmits a packet of data via the ethernet card
1024
;         d - edi - Pointer to 48 bit destination address
1025
;         t -  bx - Type of packet
1026
;         s - ecx - size of packet
1027
;         p - esi - pointer to packet data
1028
;   Destroyed registers
1029
;      eax, edx, esi, edi
1030
;
1031
;***************************************************************************
1032
proc rtl8169_transmit
1033
 
1034
	DEBUGF	1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
1035
 
1036
	push	ecx edx esi
1037
	mov	eax,MAX_ETH_FRAME_SIZE
1038
	mul	[rtl8169_tpc.cur_tx]
1039
	mov	esi,edi
1040
	; point to the current txb incase multiple tx_rings are used
1041
	mov	edi,[rtl8169_tpc.Tx_skbuff + eax * 4]
1042
	mov	eax,edi
1043
	cld
1044
; copy destination address
1045
	movsd
1046
	movsw
1047
; copy source address
1048
	mov	esi,node_addr
1049
	movsd
1050
	movsw
1051
; copy packet type
1052
	mov	[edi],bx
1053
	add	edi,2
1054
; copy the packet data
1055
	pop	esi edx ecx
1056
	push	ecx
1057
	shr	ecx,2
1058
	rep	movsd
1059
	pop	ecx
1060
	push	ecx
1061
	and	ecx,3
1062
	rep	movsb
1063
 
1064
;!!!    s += ETH_HLEN;
1065
;!!!    s &= 0x0FFF;
1066
;!!!    while (s < ETH_ZLEN)
1067
;!!!            ptxb[s++] = '\0';
1068
	mov	edi,eax
1069
	pop	ecx
1070
	push	eax
1071
	add	ecx,ETH_HLEN
1072
	and	ecx,0x0FFF
1073
	xor	al,al
1074
	add	edi,ecx
1075
    @@: cmp	ecx,ETH_ZLEN
1076
	jae	@f
1077
	stosb
1078
	inc	ecx
1079
	jmp	@b
1080
    @@: pop	eax
1081
 
1082
	mov	ebx,eax
1083
	mov	eax,sizeof.rtl8169_TxDesc
1084
	mul	[rtl8169_tpc.cur_tx]
1085
	add	eax,[rtl8169_tpc.TxDescArray]
1086
	xchg	eax,ebx
1087
	mov	[ebx + rtl8169_TxDesc.buf_addr],eax
1088
 
1089
	mov	eax,ecx
1090
	cmp	eax,ETH_ZLEN
1091
	jae	@f
1092
	mov	eax,ETH_ZLEN
1093
    @@: or	eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit
1094
	cmp	[rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
1095
	jne	@f
1096
	or	eax,RTL8169_DSB_EORbit
1097
    @@: mov	[ebx + rtl8169_TxDesc.status],eax
1098
 
1099
	RTL_W8	RTL8169_REG_TxPoll,0x40     ; set polling bit
1100
 
1101
	inc	[rtl8169_tpc.cur_tx]
1102
	and	[rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
1103
 
1104
;!!!    to = currticks() + TX_TIMEOUT;
1105
;!!!    while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
1106
	mov	ecx,TX_TIMEOUT / 10
1107
    @@: test	[ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit
1108
	jnz	@f
1109
	stdcall udelay,10
1110
	loop	@b
1111
	DEBUGF	1,"K : rtl8169_transmit: TX Time Out\n"
1112
    @@:
1113
 
1114
	ret
1115
endp
1116
 
1117
;***************************************************************************
1118
; Function
1119
;    rtl8169_poll
1120
;
1121
; Description
1122
;    Polls the ethernet card for a received packet
1123
;    Received data, if any, ends up in Ether_buffer
1124
; Destroyed register(s)
1125
;    eax, edx, ecx
1126
;
1127
;***************************************************************************
1128
proc rtl8169_poll
1129
 
1130
;       DEBUGF  1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8
1131
 
1132
	mov	word[eth_rx_data_len],0
1133
 
1134
	mov	eax,sizeof.rtl8169_RxDesc
1135
	mul	[rtl8169_tpc.cur_rx]
1136
	add	eax,[rtl8169_tpc.RxDescArray]
1137
	mov	ebx,eax
1138
 
1139
;       DEBUGF  1,"K :   rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status]
1140
 
1141
	test	[ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600
1142
	jnz	.exit
1143
 
1144
;       DEBUGF  1,"K :   rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx]
1145
 
1146
	; h/w no longer present (hotplug?) or major error, bail
1147
	RTL_R16 RTL8169_REG_IntrStatus
1148
 
1149
;       DEBUGF  1,"K :   IntrStatus = 0x%x\n",ax
1150
 
1151
	cmp	ax,0xFFFF
1152
	je	.exit
1153
 
1154
	push	eax
1155
	and	ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK)
1156
	RTL_W16 RTL8169_REG_IntrStatus,ax
1157
 
1158
	mov	eax,[ebx + rtl8169_RxDesc.status]
1159
 
1160
;       DEBUGF  1,"K :   RxDesc.status = 0x%x\n",eax
1161
 
1162
	test	eax,RTL8169_SD_RxRES
1163
	jnz	.else
1164
	and	eax,0x00001FFF
1165
;       jz      .exit.pop
1166
	add	eax,-4
1167
	mov	[eth_rx_data_len],ax
1168
 
1169
	DEBUGF	1,"K : rtl8169_poll: data length = %u\n",ax
1170
 
1171
	push	eax
1172
	mov	ecx,eax
1173
	shr	ecx,2
1174
	mov	eax,[rtl8169_tpc.cur_rx]
1175
	mov	edx,[rtl8169_tpc.RxBufferRing + eax * 4]
1176
	mov	esi,edx
1177
	mov	edi,Ether_buffer
1178
	cld
1179
	rep	movsd
1180
	pop	ecx
1181
	and	ecx,3
1182
	rep	movsb
1183
 
1184
	mov	eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE
1185
	cmp	[rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
1186
	jne	@f
1187
	or	eax,RTL8169_DSB_EORbit
1188
    @@: mov	[ebx + rtl8169_RxDesc.status],eax
1189
 
1190
	mov	[ebx + rtl8169_RxDesc.buf_addr],edx
1191
	jmp	@f
1192
  .else:
1193
	DEBUGF	1,"K : rtl8169_poll: Rx Error\n"
1194
	; FIXME: shouldn't I reset the status on an error
1195
    @@:
1196
	inc	[rtl8169_tpc.cur_rx]
1197
	and	[rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
1198
  .exit.pop:
1199
	pop	eax
1200
	and	ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK
1201
	RTL_W16 RTL8169_REG_IntrStatus,ax
1202
  .exit:
1203
	ret
1204
endp
1205
 
1206
proc rtl8169_cable
1207
	ret
1208
endp