Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
373 mikedld 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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: 593 $
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
342
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc
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
 
719
	DEBUGF	1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
720
 
721
	movzx	eax,[RegAddr]
722
	shl	eax,16
723
	or	eax,[value]
724
	or	eax,0x80000000
725
	RTL_W32 RTL8169_REG_PHYAR,eax
726
	stdcall udelay,1000
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
733
	stdcall udelay,100
734
	loop	@b
735
  .exit:
736
	ret
737
endp
738
 
739
proc RTL8169_READ_GMII_REG,RegAddr:byte
740
 
741
	DEBUGF	1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
742
 
743
	push	ecx
744
	movzx	eax,[RegAddr]
745
	shl	eax,16
746
;       or      eax,0x0
747
	RTL_W32 RTL8169_REG_PHYAR,eax
748
	stdcall udelay,1000
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
755
	stdcall udelay,100
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
823
	mov	[edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE
824
	add	esi,4
825
	add	edi,sizeof.rtl8169_RxDesc
826
	add	eax,RX_BUF_SIZE
827
	loop	@b
828
 
829
	or	[edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit
830
 
831
	ret
832
endp
833
 
834
proc rtl8169_hw_start
835
 
836
	DEBUGF	1,"K : rtl8169_hw_start\n"
837
 
838
	; Soft reset the chip
839
	RTL_W8	RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
840
	; Check that the chip has finished the reset
841
	mov	ecx,1000
842
    @@: RTL_R8	RTL8169_REG_ChipCmd
843
	and	al,RTL8169_CMD_Reset
844
	jz	@f
845
	stdcall udelay,10
846
	loop	@b
847
    @@:
848
	RTL_W8	RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock
849
	RTL_W8	RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb
850
	RTL_W8	RTL8169_REG_ETThReg,ETTh
851
	; For gigabit rtl8169
852
	RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize
853
	; Set Rx Config register
854
	RTL_R32 RTL8169_REG_RxConfig
855
	mov	ecx,[rtl8169_tpc.chipset]
856
	and	eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
857
	or	eax,rtl8169_rx_config
858
	RTL_W32 RTL8169_REG_RxConfig,eax
859
	; Set DMA burst size and Interframe Gap Time
860
	RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift)
861
	RTL_R16 RTL8169_REG_CPlusCmd
862
	RTL_W16 RTL8169_REG_CPlusCmd,ax
863
 
864
	RTL_R16 RTL8169_REG_CPlusCmd
865
	or	ax,1 shl 3
866
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_02
867
	jne	@f
868
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_03
869
	jne	@f
870
	or	ax,1 shl 14
871
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
872
	jmp	.set
873
    @@:;DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3\n"
874
  .set: RTL_W16 RTL8169_REG_CPlusCmd,ax
875
 
876
;       RTL_W16 0xE2,0x1517
877
;       RTL_W16 0xE2,0x152a
878
;       RTL_W16 0xE2,0x282a
879
	RTL_W16 0xE2,0x0000
880
 
881
	MOV	[rtl8169_tpc.cur_rx],0
882
	RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray]
883
	RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray]
884
	RTL_W8	RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
885
	stdcall udelay,10
886
	RTL_W32 RTL8169_REG_RxMissed,0
887
	call	rtl8169_set_rx_mode
888
	; no early-rx interrupts
889
	RTL_R16 RTL8169_REG_MultiIntr
890
	and	ax,0xF000
891
	RTL_W16 RTL8169_REG_MultiIntr,ax
892
	RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask
893
	ret
894
endp
895
 
896
proc udelay,msec:dword
897
	push	esi
898
	mov	esi,[msec]
899
	call	delay_ms
900
	pop	esi
901
	ret
902
endp
903
 
904
;***************************************************************************
905
;   Function
906
;      rtl8169_probe
907
;   Description
908
;      Searches for an ethernet card, enables it and clears the rx buffer
909
;      If a card was found, it enables the ethernet -> TCPIP link
910
;   Destroyed registers
911
;      eax, ebx, ecx, edx
912
;
913
;***************************************************************************
914
proc rtl8169_probe
915
 
916
	DEBUGF	1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
917
 
918
	call	rtl8169_init_board
919
 
920
	mov	ecx,MAC_ADDR_LEN
921
	mov	edx,[rtl8169_tpc.mmio_addr]
922
	add	edx,RTL8169_REG_MAC0
923
	xor	ebx,ebx
924
	; Get MAC address. FIXME: read EEPROM
925
    @@: RTL_R8	dx
926
	mov	[node_addr+ebx],al
927
	inc	edx
928
	inc	ebx
929
	loop	@b
930
 
931
	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
932
 
933
	; Config PHY
934
	stdcall rtl8169_hw_PHY_config
935
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
936
	RTL_W8	0x82,0x01
937
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_03
938
	jae	@f
939
;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
940
;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
941
   @@:
942
	cmp	[rtl8169_tpc.mcfg],MCFG_METHOD_02
943
	jne	@f
944
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
945
	RTL_W8	0x82,0x01
946
;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
947
	stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000	; w 0x0b 15 0 0
948
    @@:
949
	; if TBI is not enabled
950
	RTL_R8	RTL8169_REG_PHYstatus
951
	test	al,RTL8169_PHYS_TBI_Enable
952
	jz	.tbi_dis
953
	stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG
954
	; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
955
	and	eax,0x0C1F
956
	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
957
	stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax
958
	; enable 1000 Full Mode
959
	stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168
960
	; Enable auto-negotiation and restart auto-nigotiation
961
	stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego
962
	stdcall udelay,100
963
	mov	ecx,10000
964
	; wait for auto-negotiation process
965
    @@: dec	ecx
966
	jz	@f
967
	stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG
968
	stdcall udelay,100
969
	test	eax,RTL8169_PHY_Auto_Neco_Comp
970
	jz	@b
971
	RTL_R8	RTL8169_REG_PHYstatus
972
	jmp	@f
973
  .tbi_dis:
974
	stdcall udelay,100
975
    @@:
976
	call	rtl8169_reset
977
	ret
978
endp
979
 
980
;***************************************************************************
981
;   Function
982
;      rt8169_reset
983
;   Description
984
;      Place the chip (ie, the ethernet card) into a virgin state
985
;   Destroyed registers
986
;      eax, ebx, ecx, edx
987
;
988
;***************************************************************************
989
proc rtl8169_reset
990
 
991
	DEBUGF	1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
992
 
993
	mov	[rtl8169_tpc.TxDescArrays],rtl8169_tx_ring
994
	; Tx Desscriptor needs 256 bytes alignment
995
	mov	[rtl8169_tpc.TxDescArray],rtl8169_tx_ring
996
 
997
	mov	[rtl8169_tpc.RxDescArrays],rtl8169_rx_ring
998
	; Rx Desscriptor needs 256 bytes alignment
999
	mov	[rtl8169_tpc.RxDescArray],rtl8169_rx_ring
1000
 
1001
	call	rtl8169_init_ring
1002
	call	rtl8169_hw_start
1003
	; Construct a perfect filter frame with the mac address as first match
1004
	; and broadcast for all others
1005
	mov	edi,rtl8169_txb
1006
	or	al,-1
1007
	mov	ecx,192
1008
	cld
1009
	rep	stosb
1010
 
1011
	mov	esi,node_addr
1012
	mov	edi,rtl8169_txb
1013
	movsd
1014
	movsw
1015
 
1016
	mov	eax,[pci_data]
1017
	mov	[eth_status],eax
1018
	ret
1019
endp
1020
 
1021
;***************************************************************************
1022
;   Function
1023
;      rtl8169_transmit
1024
;   Description
1025
;      Transmits a packet of data via the ethernet card
1026
;         d - edi - Pointer to 48 bit destination address
1027
;         t -  bx - Type of packet
1028
;         s - ecx - size of packet
1029
;         p - esi - pointer to packet data
1030
;   Destroyed registers
1031
;      eax, edx, esi, edi
1032
;
1033
;***************************************************************************
1034
proc rtl8169_transmit
1035
 
1036
	DEBUGF	1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
1037
 
1038
	push	ecx edx esi
1039
	mov	eax,MAX_ETH_FRAME_SIZE
1040
	mul	[rtl8169_tpc.cur_tx]
1041
	mov	esi,edi
1042
	; point to the current txb incase multiple tx_rings are used
1043
	mov	edi,[rtl8169_tpc.Tx_skbuff + eax * 4]
1044
	mov	eax,edi
1045
	cld
1046
; copy destination address
1047
	movsd
1048
	movsw
1049
; copy source address
1050
	mov	esi,node_addr
1051
	movsd
1052
	movsw
1053
; copy packet type
1054
	mov	[edi],bx
1055
	add	edi,2
1056
; copy the packet data
1057
	pop	esi edx ecx
1058
	push	ecx
1059
	shr	ecx,2
1060
	rep	movsd
1061
	pop	ecx
1062
	push	ecx
1063
	and	ecx,3
1064
	rep	movsb
1065
 
1066
;!!!    s += ETH_HLEN;
1067
;!!!    s &= 0x0FFF;
1068
;!!!    while (s < ETH_ZLEN)
1069
;!!!            ptxb[s++] = '\0';
1070
	mov	edi,eax
1071
	pop	ecx
1072
	push	eax
1073
	add	ecx,ETH_HLEN
1074
	and	ecx,0x0FFF
1075
	xor	al,al
1076
	add	edi,ecx
1077
    @@: cmp	ecx,ETH_ZLEN
1078
	jae	@f
1079
	stosb
1080
	inc	ecx
1081
	jmp	@b
1082
    @@: pop	eax
1083
 
1084
	mov	ebx,eax
1085
	mov	eax,sizeof.rtl8169_TxDesc
1086
	mul	[rtl8169_tpc.cur_tx]
1087
	add	eax,[rtl8169_tpc.TxDescArray]
1088
	xchg	eax,ebx
1089
	mov	[ebx + rtl8169_TxDesc.buf_addr],eax
1090
 
1091
	mov	eax,ecx
1092
	cmp	eax,ETH_ZLEN
1093
	jae	@f
1094
	mov	eax,ETH_ZLEN
1095
    @@: or	eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit
1096
	cmp	[rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
1097
	jne	@f
1098
	or	eax,RTL8169_DSB_EORbit
1099
    @@: mov	[ebx + rtl8169_TxDesc.status],eax
1100
 
1101
	RTL_W8	RTL8169_REG_TxPoll,0x40     ; set polling bit
1102
 
1103
	inc	[rtl8169_tpc.cur_tx]
1104
	and	[rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
1105
 
1106
;!!!    to = currticks() + TX_TIMEOUT;
1107
;!!!    while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
1108
	mov	ecx,TX_TIMEOUT / 10
1109
    @@: test	[ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit
1110
	jnz	@f
1111
	stdcall udelay,10
1112
	loop	@b
1113
	DEBUGF	1,"K : rtl8169_transmit: TX Time Out\n"
1114
    @@:
1115
 
1116
	ret
1117
endp
1118
 
1119
;***************************************************************************
1120
; Function
1121
;    rtl8169_poll
1122
;
1123
; Description
1124
;    Polls the ethernet card for a received packet
1125
;    Received data, if any, ends up in Ether_buffer
1126
; Destroyed register(s)
1127
;    eax, edx, ecx
1128
;
1129
;***************************************************************************
1130
proc rtl8169_poll
1131
 
1132
;       DEBUGF  1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8
1133
 
1134
	mov	word[eth_rx_data_len],0
1135
 
1136
	mov	eax,sizeof.rtl8169_RxDesc
1137
	mul	[rtl8169_tpc.cur_rx]
1138
	add	eax,[rtl8169_tpc.RxDescArray]
1139
	mov	ebx,eax
1140
 
1141
;       DEBUGF  1,"K :   rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status]
1142
 
1143
	test	[ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600
1144
	jnz	.exit
1145
 
1146
;       DEBUGF  1,"K :   rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx]
1147
 
1148
	; h/w no longer present (hotplug?) or major error, bail
1149
	RTL_R16 RTL8169_REG_IntrStatus
1150
 
1151
;       DEBUGF  1,"K :   IntrStatus = 0x%x\n",ax
1152
 
1153
	cmp	ax,0xFFFF
1154
	je	.exit
1155
 
1156
	push	eax
1157
	and	ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK)
1158
	RTL_W16 RTL8169_REG_IntrStatus,ax
1159
 
1160
	mov	eax,[ebx + rtl8169_RxDesc.status]
1161
 
1162
;       DEBUGF  1,"K :   RxDesc.status = 0x%x\n",eax
1163
 
1164
	test	eax,RTL8169_SD_RxRES
1165
	jnz	.else
1166
	and	eax,0x00001FFF
1167
;       jz      .exit.pop
1168
	add	eax,-4
1169
	mov	[eth_rx_data_len],ax
1170
 
1171
	DEBUGF	1,"K : rtl8169_poll: data length = %u\n",ax
1172
 
1173
	push	eax
1174
	mov	ecx,eax
1175
	shr	ecx,2
1176
	mov	eax,[rtl8169_tpc.cur_rx]
1177
	mov	edx,[rtl8169_tpc.RxBufferRing + eax * 4]
1178
	mov	esi,edx
1179
	mov	edi,Ether_buffer
1180
	cld
1181
	rep	movsd
1182
	pop	ecx
1183
	and	ecx,3
1184
	rep	movsb
1185
 
1186
	mov	eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE
1187
	cmp	[rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
1188
	jne	@f
1189
	or	eax,RTL8169_DSB_EORbit
1190
    @@: mov	[ebx + rtl8169_RxDesc.status],eax
1191
 
1192
	mov	[ebx + rtl8169_RxDesc.buf_addr],edx
1193
	jmp	@f
1194
  .else:
1195
	DEBUGF	1,"K : rtl8169_poll: Rx Error\n"
1196
	; FIXME: shouldn't I reset the status on an error
1197
    @@:
1198
	inc	[rtl8169_tpc.cur_rx]
1199
	and	[rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
1200
  .exit.pop:
1201
	pop	eax
1202
	and	ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK
1203
	RTL_W16 RTL8169_REG_IntrStatus,ax
1204
  .exit:
1205
	ret
1206
endp
1207
 
1208
proc rtl8169_cable
1209
	ret
1210
endp