Subversion Repositories Kolibri OS

Rev

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

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