Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
869 shurf 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
373 mikedld 2
;;                                                                 ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
431 serge 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: 2465 $
30
 
31
 
2434 Serge 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
373 mikedld 36
 
2434 Serge 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
373 mikedld 71
 
2434 Serge 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
373 mikedld 84
 
2434 Serge 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
373 mikedld 90
 
2434 Serge 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
373 mikedld 96
 
2434 Serge 97
        ; Cfg9346Bits
98
        RTL8169_CFG_9346_Lock          equ 0x00
99
        RTL8169_CFG_9346_Unlock        equ 0xC0
373 mikedld 100
 
2434 Serge 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
373 mikedld 108
 
2434 Serge 109
        ; RxConfigBits
110
        RTL8169_RXC_FIFOShift          equ 13
111
        RTL8169_RXC_DMAShift           equ 8
373 mikedld 112
 
2434 Serge 113
        ; TxConfigBits
114
        RTL8169_TXC_InterFrameGapShift equ 24
115
        RTL8169_TXC_DMAShift           equ 8    ; DMA burst value (0-7) is shift this many bits
373 mikedld 116
 
2434 Serge 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
373 mikedld 126
 
2434 Serge 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
373 mikedld 132
 
2434 Serge 133
        ; GIGABIT_PHY_REG_BIT
134
        RTL8169_PHY_Restart_Auto_Nego  equ 0x0200
135
        RTL8169_PHY_Enable_Auto_Nego   equ 0x1000
373 mikedld 136
 
2434 Serge 137
        ; PHY_STAT_REG = 1;
138
        RTL8169_PHY_Auto_Neco_Comp     equ 0x0020
373 mikedld 139
 
2434 Serge 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
373 mikedld 145
 
2434 Serge 146
        ; PHY_1000_CTRL_REG = 9;
147
        RTL8169_PHY_Cap_1000_Full      equ 0x0200
148
        RTL8169_PHY_Cap_1000_Half      equ 0x0100
373 mikedld 149
 
2434 Serge 150
        RTL8169_PHY_Cap_PAUSE          equ 0x0400
151
        RTL8169_PHY_Cap_ASYM_PAUSE     equ 0x0800
373 mikedld 152
 
2434 Serge 153
        RTL8169_PHY_Cap_Null           equ 0x0
373 mikedld 154
 
2434 Serge 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
373 mikedld 161
 
2434 Serge 162
        ; _TBICSRBit
163
        RTL8169_TBI_LinkOK             equ 0x02000000
373 mikedld 164
 
2434 Serge 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
373 mikedld 170
 
171
; MAC address length
2434 Serge 172
MAC_ADDR_LEN        equ 6
373 mikedld 173
 
174
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
175
MAX_ETH_FRAME_SIZE  equ 1536
176
 
2434 Serge 177
TX_FIFO_THRESH      equ 256     ; In bytes
373 mikedld 178
 
2434 Serge 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
373 mikedld 183
 
2434 Serge 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
373 mikedld 187
 
2434 Serge 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
373 mikedld 191
 
2434 Serge 192
HZ                  equ 1000
373 mikedld 193
 
194
RTL_MIN_IO_SIZE     equ 0x80
2434 Serge 195
TX_TIMEOUT          equ (6*HZ)
373 mikedld 196
 
197
RTL8169_TIMER_EXPIRE_TIME equ 100
198
 
2434 Serge 199
ETH_HDR_LEN         equ 14
200
DEFAULT_MTU         equ 1500
373 mikedld 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
2434 Serge 215
        mov     dx, word[rtl8169_tpc.mmio_addr]
216
        add     dx, reg
373 mikedld 217
  end if
218
  if ~val8 eq al
2434 Serge 219
        mov     al, val8
373 mikedld 220
  end if
2434 Serge 221
        out     dx, al
373 mikedld 222
}
223
;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg))
224
macro RTL_W16 reg,val16 {
225
  if ~reg eq dx
2434 Serge 226
        mov     dx, word[rtl8169_tpc.mmio_addr]
227
        add     dx, reg
373 mikedld 228
  end if
229
  if ~val16 eq ax
2434 Serge 230
        mov     ax, val16
373 mikedld 231
  end if
2434 Serge 232
        out     dx, ax
373 mikedld 233
}
234
;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg))
235
macro RTL_W32 reg,val32 {
236
  if ~reg eq dx
2434 Serge 237
        mov     dx, word[rtl8169_tpc.mmio_addr]
238
        add     dx, reg
373 mikedld 239
  end if
240
  if ~val32 eq eax
2434 Serge 241
        mov     eax, val32
373 mikedld 242
  end if
2434 Serge 243
        out     dx, eax
373 mikedld 244
}
245
;!!!#define RTL_R8(reg)         inb (ioaddr + (reg))
246
macro RTL_R8 reg {
247
  if ~reg eq dx
2434 Serge 248
        mov     dx, word[rtl8169_tpc.mmio_addr]
249
        add     dx, reg
373 mikedld 250
  end if
2434 Serge 251
        in      al, dx
373 mikedld 252
}
253
;!!!#define RTL_R16(reg)        inw (ioaddr + (reg))
254
macro RTL_R16 reg {
255
  if ~reg eq dx
2434 Serge 256
        mov     dx, word[rtl8169_tpc.mmio_addr]
257
        add     dx, reg
373 mikedld 258
  end if
2434 Serge 259
        in      ax, dx
373 mikedld 260
}
261
;!!!#define RTL_R32(reg)        ((unsigned long) inl (ioaddr + (reg)))
262
macro RTL_R32 reg {
263
  if ~reg eq dx
2434 Serge 264
        mov     dx, word[rtl8169_tpc.mmio_addr]
265
        add     dx, reg
373 mikedld 266
  end if
2434 Serge 267
        in      eax, dx
373 mikedld 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
 
2434 Serge 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
373 mikedld 289
 
2434 Serge 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
373 mikedld 293
 
2434 Serge 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
373 mikedld 300
PCI_COMMAND_VGA_PALETTE equ 0x20  ; Enable palette snooping
2434 Serge 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
373 mikedld 305
 
306
struc rtl8169_TxDesc {
307
  .status    dd ?
308
  .vlan_tag  dd ?
309
  .buf_addr  dd ?
310
  .buf_Haddr dd ?
311
}
312
virtual at 0
313
  rtl8169_TxDesc rtl8169_TxDesc
314
  sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc
315
end virtual
316
 
317
struc rtl8169_RxDesc {
318
  .status    dd ?
319
  .vlan_tag  dd ?
320
  .buf_addr  dd ?
321
  .buf_Haddr dd ?
322
}
323
virtual at 0
324
  rtl8169_RxDesc rtl8169_RxDesc
325
  sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc
326
end virtual
327
 
328
virtual at eth_data_start
329
 
330
; Define the TX Descriptor
331
align 256
332
rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc
333
 
334
; Create a static buffer of size RX_BUF_SZ for each
335
; TX Descriptor.  All descriptors point to a
336
; part of this buffer
337
align 256
338
rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE
339
 
340
; Define the RX Descriptor
341
align 256
869 shurf 342
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_RxDesc
373 mikedld 343
 
344
; Create a static buffer of size RX_BUF_SZ for each
345
; RX Descriptor   All descriptors point to a
346
; part of this buffer
347
align 256
348
rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE
349
 
350
rtl8169_tpc:
2434 Serge 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
373 mikedld 357
  .TxDescArrays dd ? ; Index of Tx Descriptor buffer
358
  .RxDescArrays dd ? ; Index of Rx Descriptor buffer
2434 Serge 359
  .TxDescArray  dd ? ; Index of 256-alignment Tx Descriptor buffer
360
  .RxDescArray  dd ? ; Index of 256-alignment Rx Descriptor buffer
373 mikedld 361
  .RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array
2434 Serge 362
  .Tx_skbuff    rd NUM_TX_DESC
373 mikedld 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
2434 Serge 386
  MCFG_METHOD_15, 0xff7e1880    ; RTL8100e         // PCI-E 8139
373 mikedld 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, \
2434 Serge 398
  0x00000000, MCFG_METHOD_01    ; catch-all
373 mikedld 399
 
400
endg
401
 
2434 Serge 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
373 mikedld 408
PCI_COMMAND_VGA_PALETTE equ 0x20   ; Enable palette snooping
2434 Serge 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
373 mikedld 413
 
2434 Serge 414
PCI_VENDOR_ID           equ 0x00   ; 16 bits
415
PCI_DEVICE_ID           equ 0x02   ; 16 bits
416
PCI_COMMAND             equ 0x04   ; 16 bits
373 mikedld 417
 
2434 Serge 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
373 mikedld 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
2434 Serge 433
PCI_ROM_ADDRESS           equ 0x30      ; 32 bits
373 mikedld 434
 
435
proc CONFIG_CMD,where:byte
2434 Serge 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
373 mikedld 444
endp
445
 
446
proc pci_read_config_byte,where:dword
2434 Serge 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
373 mikedld 457
endp
458
 
459
proc pci_read_config_word,where:dword
2434 Serge 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
373 mikedld 470
endp
471
 
472
proc pci_read_config_dword,where:dword
2434 Serge 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
373 mikedld 481
endp
482
 
483
proc pci_write_config_byte,where:dword,value:byte
2434 Serge 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
373 mikedld 495
endp
496
 
497
proc pci_write_config_word,where:dword,value:word
2434 Serge 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
373 mikedld 509
endp
510
 
511
proc pci_write_config_dword,where:dword,value:dword
2434 Serge 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
373 mikedld 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
 
907 mikedld 527
;        DEBUGF  1,"K : adjust_pci_device\n"
373 mikedld 528
 
2434 Serge 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
907 mikedld 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
2434 Serge 535
        stdcall pci_write_config_word, PCI_COMMAND, ebx
373 mikedld 536
    @@:
2434 Serge 537
        stdcall pci_read_config_byte, PCI_LATENCY_TIMER
538
        cmp     al, 32
539
        jae     @f
907 mikedld 540
;        DEBUGF  1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK :   Setting to 32 clocks.\n",al
2434 Serge 541
        stdcall pci_write_config_byte, PCI_LATENCY_TIMER, 32
373 mikedld 542
    @@:
2434 Serge 543
        ret
373 mikedld 544
endp
545
 
546
; Find the start of a pci resource
547
proc pci_bar_start,index:dword
2434 Serge 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
    @@:
554
        push    eax
555
        and     eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK
556
        cmp     eax, PCI_BASE_ADDRESS_MEM_TYPE_64
557
        jne     .not64
558
        mov     eax, [index]
559
        add     eax, 4
560
        stdcall pci_read_config_dword, eax
561
        or      eax, eax
562
        jz      .not64
907 mikedld 563
;        DEBUGF  1,"K : pci_bar_start: Unhandled 64bit BAR\n"
2434 Serge 564
        add     esp, 4
565
        or      eax, -1
566
        ret
373 mikedld 567
  .not64:
2434 Serge 568
        pop     eax
569
        and     eax, PCI_BASE_ADDRESS_MEM_MASK
373 mikedld 570
  .exit:
2434 Serge 571
        ret
373 mikedld 572
endp
573
 
574
proc rtl8169_init_board
575
 
907 mikedld 576
;        DEBUGF  1,"K : rtl8169_init_board\n"
373 mikedld 577
 
2434 Serge 578
        call    adjust_pci_device
373 mikedld 579
 
2434 Serge 580
        stdcall pci_bar_start, PCI_BASE_ADDRESS_0
581
        mov     [rtl8169_tpc.mmio_addr], eax
582
        ; Soft reset the chip
583
        RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
373 mikedld 584
 
2434 Serge 585
        ; Check that the chip has finished the reset
586
        mov     ecx, 1000
373 mikedld 587
    @@:
2434 Serge 588
        RTL_R8  RTL8169_REG_ChipCmd
589
        test    al, RTL8169_CMD_Reset
590
        jz      @f
591
        stdcall udelay, 10
592
        loop    @b
593
    @@:
594
        ; identify config method
595
        RTL_R32 RTL8169_REG_TxConfig
596
        and     eax, 0x7c800000
907 mikedld 597
;        DEBUGF  1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax
2434 Serge 598
        mov     esi, mac_info-8
599
    @@:
600
        add     esi, 8
601
        mov     ecx, eax
602
        and     ecx, [esi]
603
        cmp     ecx, [esi]
604
        jne     @b
605
        mov     eax, [esi+4]
606
        mov     [rtl8169_tpc.mcfg], eax
373 mikedld 607
 
2434 Serge 608
        mov     [rtl8169_tpc.pcfg], PCFG_METHOD_3
609
        stdcall RTL8169_READ_GMII_REG, 3
610
        and     al, 0x0f
611
        or      al, al
612
        jnz     @f
613
        mov     [rtl8169_tpc.pcfg], PCFG_METHOD_1
614
        jmp     .pconf
615
    @@:
616
        dec     al
617
        jnz     .pconf
618
        mov     [rtl8169_tpc.pcfg], PCFG_METHOD_2
373 mikedld 619
  .pconf:
620
 
2434 Serge 621
        ; identify chip attached to board
622
        mov     ecx, 10
623
        mov     eax, [rtl8169_tpc.mcfg]
373 mikedld 624
    @@:
2434 Serge 625
        dec     ecx
626
        js      @f
627
        cmp     eax, [rtl_chip_info+ecx*8]
628
        jne     @b
629
        mov     [rtl8169_tpc.chipset], ecx
630
        jmp     .match
631
    @@:
632
        ; if unknown chip, assume array element #0, original RTL-8169 in this case
907 mikedld 633
;        DEBUGF  1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n"
2434 Serge 634
        RTL_R32 RTL8169_REG_TxConfig
907 mikedld 635
;        DEBUGF  1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax
373 mikedld 636
 
2434 Serge 637
        mov     [rtl8169_tpc.chipset], 0
373 mikedld 638
 
2434 Serge 639
        xor     eax, eax
640
        inc     eax
641
        ret
373 mikedld 642
 
643
  .match:
2434 Serge 644
        xor     eax, eax
645
        ret
373 mikedld 646
endp
647
 
648
proc rtl8169_hw_PHY_config
649
 
907 mikedld 650
;        DEBUGF  1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg]
373 mikedld 651
 
652
;       DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg);
653
 
2434 Serge 654
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_04
655
        jne     .not_4
373 mikedld 656
;       stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
657
;       stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e
658
;       stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb
659
;       stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a
2434 Serge 660
        stdcall RTL8169_WRITE_GMII_REG, 0x1F, 0x0002
661
        stdcall RTL8169_WRITE_GMII_REG, 0x01, 0x90D0
662
        stdcall RTL8169_WRITE_GMII_REG, 0x1F, 0x0000
663
        jmp     .exit
373 mikedld 664
  .not_4:
2434 Serge 665
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_02
666
        je      @f
667
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_03
668
        jne     .not_2_or_3
669
    @@:
670
        stdcall RTL8169_WRITE_GMII_REG, 0x1F, 0x0001
671
        stdcall RTL8169_WRITE_GMII_REG, 0x15, 0x1000
672
        stdcall RTL8169_WRITE_GMII_REG, 0x18, 0x65C7
673
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x0000
674
        stdcall RTL8169_WRITE_GMII_REG, 0x03, 0x00A1
675
        stdcall RTL8169_WRITE_GMII_REG, 0x02, 0x0008
676
        stdcall RTL8169_WRITE_GMII_REG, 0x01, 0x1020
677
        stdcall RTL8169_WRITE_GMII_REG, 0x00, 0x1000
678
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x0800
679
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x0000
680
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x7000
681
        stdcall RTL8169_WRITE_GMII_REG, 0x03, 0xFF41
682
        stdcall RTL8169_WRITE_GMII_REG, 0x02, 0xDE60
683
        stdcall RTL8169_WRITE_GMII_REG, 0x01, 0x0140
684
        stdcall RTL8169_WRITE_GMII_REG, 0x00, 0x0077
685
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x7800
686
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x7000
687
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xA000
688
        stdcall RTL8169_WRITE_GMII_REG, 0x03, 0xDF01
689
        stdcall RTL8169_WRITE_GMII_REG, 0x02, 0xDF20
690
        stdcall RTL8169_WRITE_GMII_REG, 0x01, 0xFF95
691
        stdcall RTL8169_WRITE_GMII_REG, 0x00, 0xFA00
692
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xA800
693
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xA000
694
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xB000
695
        stdcall RTL8169_WRITE_GMII_REG, 0x03, 0xFF41
696
        stdcall RTL8169_WRITE_GMII_REG, 0x02, 0xDE20
697
        stdcall RTL8169_WRITE_GMII_REG, 0x01, 0x0140
698
        stdcall RTL8169_WRITE_GMII_REG, 0x00, 0x00BB
699
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xB800
700
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xB000
701
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xF000
702
        stdcall RTL8169_WRITE_GMII_REG, 0x03, 0xDF01
703
        stdcall RTL8169_WRITE_GMII_REG, 0x02, 0xDF20
704
        stdcall RTL8169_WRITE_GMII_REG, 0x01, 0xFF95
705
        stdcall RTL8169_WRITE_GMII_REG, 0x00, 0xBF00
706
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xF800
707
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0xF000
708
        stdcall RTL8169_WRITE_GMII_REG, 0x04, 0x0000
709
        stdcall RTL8169_WRITE_GMII_REG, 0x1F, 0x0000
710
        stdcall RTL8169_WRITE_GMII_REG, 0x0B, 0x0000
711
        jmp     .exit
373 mikedld 712
  .not_2_or_3:
713
;       DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg);
907 mikedld 714
;        DEBUGF  1,"K :   tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg]
373 mikedld 715
  .exit:
2434 Serge 716
        ret
373 mikedld 717
endp
718
 
719
;proc pci_write_config_byte
720
;       ret
721
;endp
722
 
723
proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword
724
 
907 mikedld 725
;;;     DEBUGF  1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
373 mikedld 726
 
2434 Serge 727
        movzx   eax, [RegAddr]
728
        shl     eax, 16
729
        or      eax, [value]
730
        or      eax, 0x80000000
731
        RTL_W32 RTL8169_REG_PHYAR,eax
732
        stdcall udelay, 1       ;;;1000
373 mikedld 733
 
2434 Serge 734
        mov     ecx, 2000
735
        ; Check if the RTL8169 has completed writing to the specified MII register
736
    @@:
737
        RTL_R32 RTL8169_REG_PHYAR
738
        test    eax, 0x80000000
739
        jz      .exit
740
        stdcall udelay, 1       ;;;100
741
        loop    @b
373 mikedld 742
  .exit:
2434 Serge 743
        ret
373 mikedld 744
endp
745
 
746
proc RTL8169_READ_GMII_REG,RegAddr:byte
747
 
907 mikedld 748
;;;     DEBUGF  1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
373 mikedld 749
 
2434 Serge 750
        push    ecx
751
        movzx   eax, [RegAddr]
752
        shl     eax, 16
373 mikedld 753
;       or      eax,0x0
2434 Serge 754
        RTL_W32 RTL8169_REG_PHYAR,eax
755
        stdcall udelay, 1       ;;;1000
373 mikedld 756
 
2434 Serge 757
        mov     ecx, 2000
758
        ; Check if the RTL8169 has completed retrieving data from the specified MII register
759
    @@:
760
        RTL_R32 RTL8169_REG_PHYAR
761
        test    eax, 0x80000000
762
        jnz     .exit
763
        stdcall udelay, 1       ;;;100
764
        loop    @b
373 mikedld 765
 
2434 Serge 766
        or      eax, -1
767
        pop     ecx
768
        ret
373 mikedld 769
  .exit:
2434 Serge 770
        RTL_R32 RTL8169_REG_PHYAR
771
        and     eax, 0xFFFF
772
        pop     ecx
773
        ret
373 mikedld 774
endp
775
 
776
proc rtl8169_set_rx_mode
777
 
907 mikedld 778
;        DEBUGF  1,"K : rtl8169_set_rx_mode\n"
373 mikedld 779
 
2434 Serge 780
        ; IFF_ALLMULTI
781
        ; Too many to filter perfectly -- accept all multicasts
782
        RTL_R32 RTL8169_REG_RxConfig
783
        mov     ecx, [rtl8169_tpc.chipset]
784
        and     eax, [rtl_chip_info + ecx * 8 + 4]; RxConfigMask
785
        or      eax, rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys)
786
        RTL_W32 RTL8169_REG_RxConfig,eax
373 mikedld 787
 
2434 Serge 788
        ; Multicast hash filter
789
        RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff
790
        RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff
791
        ret
373 mikedld 792
endp
793
 
794
proc rtl8169_init_ring
795
 
907 mikedld 796
;        DEBUGF  1,"K : rtl8169_init_ring\n"
373 mikedld 797
 
2434 Serge 798
        xor     eax, eax
799
        mov     [rtl8169_tpc.cur_rx], eax
800
        mov     [rtl8169_tpc.cur_tx], eax
373 mikedld 801
 
2434 Serge 802
        mov     edi, [rtl8169_tpc.TxDescArray]
803
        mov     ecx, (NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4
804
        cld
805
        rep stosd
806
        mov     edi, [rtl8169_tpc.RxDescArray]
807
        mov     ecx, (NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4
808
        rep stosd
373 mikedld 809
 
2434 Serge 810
        mov     edi, rtl8169_tpc.Tx_skbuff
811
        mov     eax, rtl8169_txb
812
        mov     ecx, NUM_TX_DESC
813
    @@:
814
        stosd
815
        inc     eax           ; add eax,RX_BUF_SIZE ???
816
        loop    @b
373 mikedld 817
 
818
;!!!    for (i = 0; i < NUM_RX_DESC; i++) {
819
;!!!            if (i == (NUM_RX_DESC - 1))
820
;!!!                    tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE;
821
;!!!            else
822
;!!!                    tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE;
823
;!!!            tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
824
;!!!            tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]);
825
;!!!    }
2434 Serge 826
        mov     esi, rtl8169_tpc.RxBufferRing
827
        mov     edi, [rtl8169_tpc.RxDescArray]
828
        mov     eax, rtl8169_rxb
829
        mov     ecx, NUM_RX_DESC
830
    @@:
831
        mov     [esi], eax
832
        mov     [edi+rtl8169_RxDesc.buf_addr], eax
833
        sub     [edi+rtl8169_RxDesc.buf_addr], OS_BASE                          ; shurf 28.09.2008
834
        mov     [edi+rtl8169_RxDesc.status], RTL8169_DSB_OWNbit or RX_BUF_SIZE
835
        add     esi, 4
836
        add     edi, sizeof.rtl8169_RxDesc
837
        add     eax, RX_BUF_SIZE
838
        loop    @b
373 mikedld 839
 
2434 Serge 840
        or      [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status], RTL8169_DSB_EORbit
373 mikedld 841
 
2434 Serge 842
        ret
373 mikedld 843
endp
844
 
845
proc rtl8169_hw_start
846
 
907 mikedld 847
;        DEBUGF  1,"K : rtl8169_hw_start\n"
373 mikedld 848
 
2434 Serge 849
        ; Soft reset the chip
850
        RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
851
        ; Check that the chip has finished the reset
852
        mov     ecx, 1000
373 mikedld 853
    @@:
2434 Serge 854
        RTL_R8  RTL8169_REG_ChipCmd
855
        and     al, RTL8169_CMD_Reset
856
        jz      @f
857
        stdcall udelay, 10
858
        loop    @b
859
    @@:
860
        RTL_W8  RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock
861
        RTL_W8  RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb
862
        RTL_W8  RTL8169_REG_ETThReg,ETTh
863
        ; For gigabit rtl8169
864
        RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize
865
        ; Set Rx Config register
866
        RTL_R32 RTL8169_REG_RxConfig
867
        mov     ecx, [rtl8169_tpc.chipset]
868
        and     eax, [rtl_chip_info + ecx * 8 + 4]; RxConfigMask
869
        or      eax, rtl8169_rx_config
870
        RTL_W32 RTL8169_REG_RxConfig,eax
871
        ; Set DMA burst size and Interframe Gap Time
872
        RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift)
873
        RTL_R16 RTL8169_REG_CPlusCmd
874
        RTL_W16 RTL8169_REG_CPlusCmd,ax
373 mikedld 875
 
2434 Serge 876
        RTL_R16 RTL8169_REG_CPlusCmd
877
        or      ax, 1 shl 3
878
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_02
879
        jne     @f
880
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_03
881
        jne     @f
882
        or      ax, 1 shl 14
373 mikedld 883
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
2434 Serge 884
        jmp     .set
373 mikedld 885
    @@:;DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0xE0: bit-3\n"
2434 Serge 886
  .set:
887
        RTL_W16 RTL8169_REG_CPlusCmd,ax
373 mikedld 888
 
889
;       RTL_W16 0xE2,0x1517
890
;       RTL_W16 0xE2,0x152a
891
;       RTL_W16 0xE2,0x282a
2434 Serge 892
        RTL_W16 0xE2,0x0000
373 mikedld 893
 
2434 Serge 894
        MOV     [rtl8169_tpc.cur_rx],0
895
        push    eax                                                             ; shurf 28.09.2008
896
        mov     eax, [rtl8169_tpc.TxDescArray]                                  ; shurf 28.09.2008
897
        sub     eax, OS_BASE                                                    ; shurf 28.09.2008
898
        RTL_W32 RTL8169_REG_TxDescStartAddr,eax ;[rtl8169_tpc.TxDescArray]      ; shurf 28.09.2008
899
        mov     eax, [rtl8169_tpc.RxDescArray]                                  ; shurf 28.09.2008
900
        sub     eax, OS_BASE                                                    ; shurf 28.09.2008
901
        RTL_W32 RTL8169_REG_RxDescStartAddr,eax ;[rtl8169_tpc.RxDescArray]      ; shurf 28.09.2008
902
        pop     eax                                                             ; shurf 28.09.2008
903
        RTL_W8  RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
904
        stdcall udelay, 10
905
        RTL_W32 RTL8169_REG_RxMissed,0
906
        call    rtl8169_set_rx_mode
907
        ; no early-rx interrupts
908
        RTL_R16 RTL8169_REG_MultiIntr
909
        and     ax, 0xF000
910
        RTL_W16 RTL8169_REG_MultiIntr,ax
911
        RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask
912
        ret
373 mikedld 913
endp
914
 
915
proc udelay,msec:dword
2434 Serge 916
        push    esi
917
        mov     esi, [msec]
918
        call    delay_ms
919
        pop     esi
920
        ret
373 mikedld 921
endp
922
 
923
;***************************************************************************
924
;   Function
925
;      rtl8169_probe
926
;   Description
927
;      Searches for an ethernet card, enables it and clears the rx buffer
928
;      If a card was found, it enables the ethernet -> TCPIP link
929
;   Destroyed registers
930
;      eax, ebx, ecx, edx
931
;
932
;***************************************************************************
933
proc rtl8169_probe
934
 
907 mikedld 935
;        DEBUGF  1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
373 mikedld 936
 
2434 Serge 937
        call    rtl8169_init_board
373 mikedld 938
 
2434 Serge 939
        mov     ecx, MAC_ADDR_LEN
940
        mov     edx, [rtl8169_tpc.mmio_addr]
941
        add     edx, RTL8169_REG_MAC0
942
        xor     ebx, ebx
943
        ; Get MAC address. FIXME: read EEPROM
944
    @@:
945
        RTL_R8  dx
946
        mov     [node_addr+ebx], al
947
        inc     edx
948
        inc     ebx
949
        loop    @b
373 mikedld 950
 
907 mikedld 951
;        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
373 mikedld 952
 
2434 Serge 953
        ; Config PHY
954
        stdcall rtl8169_hw_PHY_config
373 mikedld 955
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
2434 Serge 956
        RTL_W8  0x82,0x01
957
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_03
958
        jae     @f
373 mikedld 959
;       DEBUGF  1,"K :   Set PCI Latency=0x40\n"
960
;       stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
961
   @@:
2434 Serge 962
        cmp     [rtl8169_tpc.mcfg], MCFG_METHOD_02
963
        jne     @f
373 mikedld 964
;       DEBUGF  1,"K :   Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
2434 Serge 965
        RTL_W8  0x82,0x01
373 mikedld 966
;       DEBUGF  1,"K :   Set PHY Reg 0x0bh = 0x00h\n"
2434 Serge 967
        stdcall RTL8169_WRITE_GMII_REG, 0x0b, 0x0000    ; w 0x0b 15 0 0
373 mikedld 968
    @@:
2434 Serge 969
        ; if TBI is not enabled
970
        RTL_R8  RTL8169_REG_PHYstatus
971
        test    al, RTL8169_PHYS_TBI_Enable
972
        jz      .tbi_dis
973
        stdcall RTL8169_READ_GMII_REG, RTL8169_PHY_AUTO_NEGO_REG
974
        ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
975
        and     eax, 0x0C1F
976
        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
977
        stdcall RTL8169_WRITE_GMII_REG, RTL8169_PHY_AUTO_NEGO_REG, eax
978
        ; enable 1000 Full Mode
979
        stdcall RTL8169_WRITE_GMII_REG, RTL8169_PHY_1000_CTRL_REG, RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half; rtl8168
980
        ; Enable auto-negotiation and restart auto-nigotiation
981
        stdcall RTL8169_WRITE_GMII_REG, RTL8169_PHY_CTRL_REG, RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego
982
        stdcall udelay, 100
983
        mov     ecx, 10000
984
        ; wait for auto-negotiation process
985
    @@:
986
        dec     ecx
987
        jz      @f
988
        stdcall RTL8169_READ_GMII_REG, RTL8169_PHY_STAT_REG
989
        stdcall udelay, 100
990
        test    eax, RTL8169_PHY_Auto_Neco_Comp
991
        jz      @b
992
        RTL_R8  RTL8169_REG_PHYstatus
993
        jmp     @f
373 mikedld 994
  .tbi_dis:
2434 Serge 995
        stdcall udelay, 100
373 mikedld 996
    @@:
2434 Serge 997
        call    rtl8169_reset
998
        ret
373 mikedld 999
endp
1000
 
1001
;***************************************************************************
1002
;   Function
1003
;      rt8169_reset
1004
;   Description
1005
;      Place the chip (ie, the ethernet card) into a virgin state
1006
;   Destroyed registers
1007
;      eax, ebx, ecx, edx
1008
;
1009
;***************************************************************************
1010
proc rtl8169_reset
1011
 
907 mikedld 1012
;        DEBUGF  1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
373 mikedld 1013
 
2434 Serge 1014
        mov     [rtl8169_tpc.TxDescArrays], rtl8169_tx_ring
1015
        ; Tx Desscriptor needs 256 bytes alignment
1016
        mov     [rtl8169_tpc.TxDescArray], rtl8169_tx_ring
373 mikedld 1017
 
2434 Serge 1018
        mov     [rtl8169_tpc.RxDescArrays], rtl8169_rx_ring
1019
        ; Rx Desscriptor needs 256 bytes alignment
1020
        mov     [rtl8169_tpc.RxDescArray], rtl8169_rx_ring
373 mikedld 1021
 
2434 Serge 1022
        call    rtl8169_init_ring
1023
        call    rtl8169_hw_start
1024
        ; Construct a perfect filter frame with the mac address as first match
1025
        ; and broadcast for all others
1026
        mov     edi, rtl8169_txb
1027
        or      al, -1
1028
        mov     ecx, 192
1029
        cld
1030
        rep stosb
373 mikedld 1031
 
2434 Serge 1032
        mov     esi, node_addr
1033
        mov     edi, rtl8169_txb
1034
        movsd
1035
        movsw
373 mikedld 1036
 
2434 Serge 1037
        mov     eax, [pci_data]
1038
        mov     [eth_status], eax
1039
        ret
373 mikedld 1040
endp
1041
 
1042
;***************************************************************************
1043
;   Function
1044
;      rtl8169_transmit
1045
;   Description
1046
;      Transmits a packet of data via the ethernet card
1047
;         d - edi - Pointer to 48 bit destination address
1048
;         t -  bx - Type of packet
1049
;         s - ecx - size of packet
1050
;         p - esi - pointer to packet data
1051
;   Destroyed registers
1052
;      eax, edx, esi, edi
1053
;
1054
;***************************************************************************
1055
proc rtl8169_transmit
1056
 
907 mikedld 1057
;        DEBUGF  1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
373 mikedld 1058
 
2434 Serge 1059
        push    ecx edx esi
1060
        mov     eax, MAX_ETH_FRAME_SIZE
1061
        mul     [rtl8169_tpc.cur_tx]
1062
        mov     esi, edi
1063
        ; point to the current txb incase multiple tx_rings are used
1064
        mov     edi, [rtl8169_tpc.Tx_skbuff + eax * 4]
1065
        mov     eax, edi
1066
        cld
373 mikedld 1067
; copy destination address
2434 Serge 1068
        movsd
1069
        movsw
373 mikedld 1070
; copy source address
2434 Serge 1071
        mov     esi, node_addr
1072
        movsd
1073
        movsw
373 mikedld 1074
; copy packet type
2434 Serge 1075
        mov     [edi], bx
1076
        add     edi, 2
373 mikedld 1077
; copy the packet data
2434 Serge 1078
        pop     esi edx ecx
1079
        push    ecx
1080
        shr     ecx, 2
1081
        rep movsd
1082
        pop     ecx
1083
        push    ecx
1084
        and     ecx, 3
1085
        rep movsb
373 mikedld 1086
 
1087
;!!!    s += ETH_HLEN;
1088
;!!!    s &= 0x0FFF;
1089
;!!!    while (s < ETH_ZLEN)
1090
;!!!            ptxb[s++] = '\0';
2434 Serge 1091
        mov     edi, eax
1092
        pop     ecx
1093
        push    eax
1094
        add     ecx, ETH_HLEN
1095
        and     ecx, 0x0FFF
1096
        xor     al, al
1097
        add     edi, ecx
1098
    @@:
1099
        cmp     ecx, ETH_ZLEN
1100
        jae     @f
1101
        stosb
1102
        inc     ecx
1103
        jmp     @b
1104
    @@:
1105
        pop     eax
373 mikedld 1106
 
2434 Serge 1107
        mov     ebx, eax
1108
        mov     eax, sizeof.rtl8169_TxDesc
1109
        mul     [rtl8169_tpc.cur_tx]
1110
        add     eax, [rtl8169_tpc.TxDescArray]
1111
        xchg    eax, ebx
1112
        mov     [ebx + rtl8169_TxDesc.buf_addr], eax
1113
        sub     [ebx + rtl8169_TxDesc.buf_addr], OS_BASE                                ; shurf 28.09.2008
373 mikedld 1114
 
2434 Serge 1115
        mov     eax, ecx
1116
        cmp     eax, ETH_ZLEN
1117
        jae     @f
1118
        mov     eax, ETH_ZLEN
1119
    @@:
1120
        or      eax, RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit
1121
        cmp     [rtl8169_tpc.cur_tx], NUM_TX_DESC - 1
1122
        jne     @f
1123
        or      eax, RTL8169_DSB_EORbit
1124
    @@:
1125
        mov     [ebx + rtl8169_TxDesc.status], eax
373 mikedld 1126
 
2434 Serge 1127
        RTL_W8  RTL8169_REG_TxPoll,0x40     ; set polling bit
373 mikedld 1128
 
2434 Serge 1129
        inc     [rtl8169_tpc.cur_tx]
1130
        and     [rtl8169_tpc.cur_tx], NUM_TX_DESC - 1
373 mikedld 1131
 
1132
;!!!    to = currticks() + TX_TIMEOUT;
1133
;!!!    while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to));        /* wait */
2434 Serge 1134
        mov     ecx, TX_TIMEOUT / 10
1135
    @@:
1136
        test    [ebx + rtl8169_TxDesc.status], RTL8169_DSB_OWNbit
1137
        jnz     @f
1138
        stdcall udelay, 10
1139
        loop    @b
907 mikedld 1140
;        DEBUGF  1,"K : rtl8169_transmit: TX Time Out\n"
373 mikedld 1141
    @@:
1142
 
2434 Serge 1143
        ret
373 mikedld 1144
endp
1145
 
1146
;***************************************************************************
1147
; Function
1148
;    rtl8169_poll
1149
;
1150
; Description
1151
;    Polls the ethernet card for a received packet
1152
;    Received data, if any, ends up in Ether_buffer
1153
; Destroyed register(s)
1154
;    eax, edx, ecx
1155
;
1156
;***************************************************************************
1157
proc rtl8169_poll
1158
 
1159
;       DEBUGF  1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8
1160
 
2434 Serge 1161
        mov     word[eth_rx_data_len], 0
373 mikedld 1162
 
2434 Serge 1163
        mov     eax, sizeof.rtl8169_RxDesc
1164
        mul     [rtl8169_tpc.cur_rx]
1165
        add     eax, [rtl8169_tpc.RxDescArray]
1166
        mov     ebx, eax
373 mikedld 1167
 
1168
;       DEBUGF  1,"K :   rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status]
1169
 
2434 Serge 1170
        test    [ebx + rtl8169_RxDesc.status], RTL8169_DSB_OWNbit; 0x80000600
1171
        jnz     .exit
373 mikedld 1172
 
1173
;       DEBUGF  1,"K :   rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx]
1174
 
2434 Serge 1175
        ; h/w no longer present (hotplug?) or major error, bail
1176
        RTL_R16 RTL8169_REG_IntrStatus
373 mikedld 1177
 
1178
;       DEBUGF  1,"K :   IntrStatus = 0x%x\n",ax
1179
 
2434 Serge 1180
        cmp     ax, 0xFFFF
1181
        je      .exit
373 mikedld 1182
 
2434 Serge 1183
        push    eax
1184
        and     ax, not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK)
1185
        RTL_W16 RTL8169_REG_IntrStatus,ax
373 mikedld 1186
 
2434 Serge 1187
        mov     eax, [ebx + rtl8169_RxDesc.status]
373 mikedld 1188
 
1189
;       DEBUGF  1,"K :   RxDesc.status = 0x%x\n",eax
1190
 
2434 Serge 1191
        test    eax, RTL8169_SD_RxRES
1192
        jnz     .else
1193
        and     eax, 0x00001FFF
373 mikedld 1194
;       jz      .exit.pop
2434 Serge 1195
        add     eax, -4
1196
        mov     [eth_rx_data_len], ax
373 mikedld 1197
 
907 mikedld 1198
;        DEBUGF  1,"K : rtl8169_poll: data length = %u\n",ax
373 mikedld 1199
 
2434 Serge 1200
        push    eax
1201
        mov     ecx, eax
1202
        shr     ecx, 2
1203
        mov     eax, [rtl8169_tpc.cur_rx]
1204
        mov     edx, [rtl8169_tpc.RxBufferRing + eax * 4]
1205
        mov     esi, edx
1206
        mov     edi, Ether_buffer
1207
        cld
1208
        rep movsd
1209
        pop     ecx
1210
        and     ecx, 3
1211
        rep movsb
373 mikedld 1212
 
2434 Serge 1213
        mov     eax, RTL8169_DSB_OWNbit or RX_BUF_SIZE
1214
        cmp     [rtl8169_tpc.cur_rx], NUM_RX_DESC - 1
1215
        jne     @f
1216
        or      eax, RTL8169_DSB_EORbit
1217
    @@:
1218
        mov     [ebx + rtl8169_RxDesc.status], eax
373 mikedld 1219
 
2434 Serge 1220
        mov     [ebx + rtl8169_RxDesc.buf_addr], edx
1221
        sub     [ebx + rtl8169_RxDesc.buf_addr], OS_BASE                                ; shurf 28.09.2008
1222
        jmp     @f
373 mikedld 1223
  .else:
907 mikedld 1224
;        DEBUGF  1,"K : rtl8169_poll: Rx Error\n"
2434 Serge 1225
        ; FIXME: shouldn't I reset the status on an error
373 mikedld 1226
    @@:
2434 Serge 1227
        inc     [rtl8169_tpc.cur_rx]
1228
        and     [rtl8169_tpc.cur_rx], NUM_RX_DESC - 1
373 mikedld 1229
  .exit.pop:
2434 Serge 1230
        pop     eax
1231
        and     ax, RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK
1232
        RTL_W16 RTL8169_REG_IntrStatus,ax
373 mikedld 1233
  .exit:
2434 Serge 1234
        ret
373 mikedld 1235
endp
1236
 
1237
proc rtl8169_cable
2434 Serge 1238
        ret
373 mikedld 1239
endp