Subversion Repositories Kolibri OS

Rev

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

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