Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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