Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
866 shurf 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  FORCEDETH.INC                                                  ;;
7
;;                                                                 ;;
8
;;  Ethernet driver for Kolibri OS                                 ;;
9
;;                                                                 ;;
10
;;  Version 0.1  24 June 2008 - 23 Sep 2008                        ;;
11
;;                                                                 ;;
12
;;  Driver for chips of NVIDIA nForce2                             ;;
13
;;  References:                                                    ;;
14
;;    forcedeth.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 2008 shurf,                                          ;;
23
;;   cit.utc@gmail.com                                             ;;
24
;;                                                                 ;;
25
;;  See file COPYING for details                                   ;;
26
;;                                                                 ;;
27
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28
 
29
$Revision: 2288 $
30
 
31
;********************************************************************
32
;   Interface
33
;      forcedeth_reset
34
;      forcedeth_probe
35
;      forcedeth_poll
36
;      forcedeth_transmit
37
;      forcedeth_cable
38
;
39
;********************************************************************
40
 
41
;**************************************************************************
42
; forcedeth Register Definitions
43
;**************************************************************************
44
 
2288 clevermous 45
PCI_REG_COMMAND                 equ     0x04    ; command register
866 shurf 46
 
2288 clevermous 47
PCI_COMMAND_IO                  equ     0x01    ; Enable response in I/O space
48
PCI_COMMAND_MASTER              equ     0x04    ; Enable bus mastering
49
PCI_LATENCY_TIMER               equ     0x0d    ; 8 bits
866 shurf 50
 
2288 clevermous 51
PCI_VENDOR_ID                   equ     0x00    ; 16 bit
52
PCI_REVISION_ID                 equ     0x08    ; 8 bits
866 shurf 53
 
2288 clevermous 54
PCI_BASE_ADDRESS_0              equ     0x10    ; 32 bits
55
PCI_BASE_ADDRESS_1              equ     0x14    ; 32 bits
56
PCI_BASE_ADDRESS_2              equ     0x18    ; 32 bits
57
PCI_BASE_ADDRESS_3              equ     0x1c    ; 32 bits
58
PCI_BASE_ADDRESS_4              equ     0x20    ; 32 bits
59
PCI_BASE_ADDRESS_5              equ     0x24    ; 32 bits
866 shurf 60
 
2288 clevermous 61
PCI_BASE_ADDRESS_SPACE_IO       equ     0x01
62
PCI_BASE_ADDRESS_IO_MASK        equ     (not 0x03)
63
PCI_BASE_ADDRESS_MEM_MASK       equ     (not 0x0f)
866 shurf 64
 
2288 clevermous 65
PCI_BASE_ADDRESS_MEM_TYPE_MASK  equ     0x06
66
PCI_BASE_ADDRESS_MEM_TYPE_32    equ     0x00    ; 32 bit address
67
PCI_BASE_ADDRESS_MEM_TYPE_1M    equ     0x02    ; Below 1M [obsolete]
68
PCI_BASE_ADDRESS_MEM_TYPE_64    equ     0x04    ; 64 bit address
866 shurf 69
 
70
; NIC specific static variables go here
2288 clevermous 71
PCI_DEVICE_ID_NVIDIA_NVENET_1   equ     0x01c3
72
PCI_DEVICE_ID_NVIDIA_NVENET_2   equ     0x0066
73
PCI_DEVICE_ID_NVIDIA_NVENET_4   equ     0x0086
74
PCI_DEVICE_ID_NVIDIA_NVENET_5   equ     0x008c
75
PCI_DEVICE_ID_NVIDIA_NVENET_3   equ     0x00d6
76
PCI_DEVICE_ID_NVIDIA_NVENET_7   equ     0x00df
77
PCI_DEVICE_ID_NVIDIA_NVENET_6   equ     0x00e6
78
PCI_DEVICE_ID_NVIDIA_NVENET_8   equ     0x0056
79
PCI_DEVICE_ID_NVIDIA_NVENET_9   equ     0x0057
80
PCI_DEVICE_ID_NVIDIA_NVENET_10  equ     0x0037
81
PCI_DEVICE_ID_NVIDIA_NVENET_11  equ     0x0038
82
PCI_DEVICE_ID_NVIDIA_NVENET_12  equ     0x0268
83
PCI_DEVICE_ID_NVIDIA_NVENET_13  equ     0x0269
84
PCI_DEVICE_ID_NVIDIA_NVENET_14  equ     0x0372
85
PCI_DEVICE_ID_NVIDIA_NVENET_15  equ     0x0373
866 shurf 86
 
2288 clevermous 87
ETH_DATA_LEN                    equ     1500
866 shurf 88
 
89
; rx/tx mac addr + type + vlan + align + slack
2288 clevermous 90
RX_NIC_BUFSIZE                  equ     (ETH_DATA_LEN + 64)
866 shurf 91
; even more slack
2288 clevermous 92
RX_ALLOC_BUFSIZE                equ     (ETH_DATA_LEN + 128)
866 shurf 93
 
2288 clevermous 94
NvRegIrqStatus                  equ     0x00
95
NvRegIrqMask                    equ     0x04
96
NvRegUnknownSetupReg6           equ     0x08
97
NvRegPollingInterval            equ     0x0c
98
NvRegMacReset                   equ     0x3c
99
NvRegMisc1                      equ     0x80
100
NvRegTransmitterControl         equ     0x84
101
NvRegTransmitterStatus          equ     0x88
102
NvRegPacketFilterFlags          equ     0x8c
103
NvRegOffloadConfig              equ     0x90
104
NvRegReceiverControl            equ     0x94
105
NvRegReceiverStatus             equ     0x98
106
NvRegRandomSeed                 equ     0x9c
107
NvRegUnknownSetupReg1           equ     0xA0
108
NvRegUnknownSetupReg2           equ     0xA4
109
NvRegMacAddrA                   equ     0xA8    ; MAC address low
110
NvRegMacAddrB                   equ     0xAC    ; MAC address high
111
NvRegMulticastAddrA             equ     0xB0
112
NvRegMulticastAddrB             equ     0xB4
113
NvRegMulticastMaskA             equ     0xB8
114
NvRegMulticastMaskB             equ     0xBC
115
NvRegPhyInterface               equ     0xC0
116
NvRegTxRingPhysAddr             equ     0x100
117
NvRegRxRingPhysAddr             equ     0x104
118
NvRegRingSizes                  equ     0x108
119
NvRegUnknownTransmitterReg      equ     0x10c
120
NvRegLinkSpeed                  equ     0x110
121
NvRegUnknownSetupReg5           equ     0x130
122
NvRegUnknownSetupReg3           equ     0x13c
123
NvRegTxRxControl                equ     0x144
124
NvRegMIIStatus                  equ     0x180
125
NvRegUnknownSetupReg4           equ     0x184
126
NvRegAdapterControl             equ     0x188
127
NvRegMIISpeed                   equ     0x18c
128
NvRegMIIControl                 equ     0x190
129
NvRegMIIData                    equ     0x194
130
NvRegWakeUpFlags                equ     0x200
131
NvRegPowerState                 equ     0x26c
132
NvRegPowerState2                equ     0x600
866 shurf 133
 
2288 clevermous 134
NVREG_UNKSETUP1_VAL             equ     0x16070f
135
NVREG_UNKSETUP2_VAL             equ     0x16
136
NVREG_UNKSETUP3_VAL1            equ     0x200010
137
NVREG_UNKSETUP4_VAL             equ     8
138
NVREG_UNKSETUP5_BIT31           equ     (1 shl 31)
139
NVREG_UNKSETUP6_VAL             equ     3
866 shurf 140
 
2288 clevermous 141
NVREG_TXRXCTL_RXCHECK           equ     0x0400
142
NVREG_MIISTAT_ERROR             equ     0x0001
143
NVREG_MIISTAT_MASK              equ     0x000f
144
NVREG_MIISTAT_MASK2             equ     0x000f
145
NVREG_MIICTL_INUSE              equ     0x08000
146
NVREG_MIICTL_WRITE              equ     0x00400
147
NVREG_MIICTL_ADDRSHIFT          equ     5
866 shurf 148
 
2288 clevermous 149
NVREG_MIISPEED_BIT8             equ     (1 shl 8)
150
NVREG_MIIDELAY                  equ     5
866 shurf 151
 
2288 clevermous 152
NVREG_IRQ_RX_ERROR              equ     0x0001
153
NVREG_IRQ_RX                    equ     0x0002
154
NVREG_IRQ_RX_NOBUF              equ     0x0004
155
NVREG_IRQ_LINK                  equ     0x0040
156
NVREG_IRQ_TIMER                 equ     0x0020
157
NVREG_IRQMASK_WANTED_2          equ     0x0147
866 shurf 158
 
2288 clevermous 159
NVREG_IRQ_RX_ALL                equ     (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF)
160
NVREG_IRQ_TX_ALL                equ     0       ; ???????????
161
NVREG_IRQ_OTHER_ALL             equ     (NVREG_IRQ_LINK or NVREG_IRQ_TIMER)
866 shurf 162
 
2288 clevermous 163
NVREG_IRQSTAT_MASK              equ     0x1ff
866 shurf 164
 
2288 clevermous 165
NVREG_TXRXCTL_KICK              equ     0x0001
166
NVREG_TXRXCTL_BIT1              equ     0x0002
167
NVREG_TXRXCTL_BIT2              equ     0x0004
168
NVREG_TXRXCTL_IDLE              equ     0x0008
169
NVREG_TXRXCTL_RESET             equ     0x0010
170
NVREG_TXRXCTL_RXCHECK           equ     0x0400
866 shurf 171
 
2288 clevermous 172
NVREG_MCASTADDRA_FORCE          equ     0x01
866 shurf 173
 
2288 clevermous 174
NVREG_MAC_RESET_ASSERT          equ     0x0F3
866 shurf 175
 
2288 clevermous 176
NVREG_MISC1_HD                  equ     0x02
177
NVREG_MISC1_FORCE               equ     0x3b0f3c
866 shurf 178
 
2288 clevermous 179
NVREG_PFF_ALWAYS                equ     0x7F0008
180
NVREG_PFF_PROMISC               equ     0x80
181
NVREG_PFF_MYADDR                equ     0x20
866 shurf 182
 
2288 clevermous 183
NVREG_OFFLOAD_HOMEPHY           equ     0x601
184
NVREG_OFFLOAD_NORMAL            equ     RX_NIC_BUFSIZE
866 shurf 185
 
2288 clevermous 186
NVREG_RNDSEED_MASK              equ     0x00ff
187
NVREG_RNDSEED_FORCE             equ     0x7f00
188
NVREG_RNDSEED_FORCE2            equ     0x2d00
189
NVREG_RNDSEED_FORCE3            equ     0x7400
866 shurf 190
 
191
; NVREG_POLL_DEFAULT is the interval length of the timer source on the nic
192
; NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
2288 clevermous 193
NVREG_POLL_DEFAULT              equ     970
866 shurf 194
 
2288 clevermous 195
NVREG_ADAPTCTL_START            equ     0x02
196
NVREG_ADAPTCTL_LINKUP           equ     0x04
197
NVREG_ADAPTCTL_PHYVALID         equ     0x40000
198
NVREG_ADAPTCTL_RUNNING          equ     0x100000
199
NVREG_ADAPTCTL_PHYSHIFT         equ     24
866 shurf 200
 
2288 clevermous 201
NVREG_WAKEUPFLAGS_VAL           equ     0x7770
866 shurf 202
 
2288 clevermous 203
NVREG_POWERSTATE_POWEREDUP      equ     0x8000
204
NVREG_POWERSTATE_VALID          equ     0x0100
205
NVREG_POWERSTATE_MASK           equ     0x0003
206
NVREG_POWERSTATE_D0             equ     0x0000
207
NVREG_POWERSTATE_D1             equ     0x0001
208
NVREG_POWERSTATE_D2             equ     0x0002
209
NVREG_POWERSTATE_D3             equ     0x0003
866 shurf 210
 
2288 clevermous 211
NVREG_POWERSTATE2_POWERUP_MASK  equ     0x0F11
212
NVREG_POWERSTATE2_POWERUP_REV_A3 equ    0x0001
866 shurf 213
 
2288 clevermous 214
NVREG_RCVCTL_START              equ     0x01
215
NVREG_RCVSTAT_BUSY              equ     0x01
866 shurf 216
 
2288 clevermous 217
NVREG_XMITCTL_START             equ     0x01
866 shurf 218
 
2288 clevermous 219
NVREG_LINKSPEED_FORCE           equ     0x10000
220
NVREG_LINKSPEED_10              equ     1000
221
NVREG_LINKSPEED_100             equ     100
222
NVREG_LINKSPEED_1000            equ     50
866 shurf 223
 
2288 clevermous 224
NVREG_RINGSZ_TXSHIFT            equ     0
225
NVREG_RINGSZ_RXSHIFT            equ     16
866 shurf 226
 
2288 clevermous 227
LPA_1000FULL                    equ     0x0800
866 shurf 228
 
229
; Link partner ability register.
2288 clevermous 230
LPA_SLCT                        equ     0x001f  ; Same as advertise selector
231
LPA_10HALF                      equ     0x0020  ; Can do 10mbps half-duplex
232
LPA_10FULL                      equ     0x0040  ; Can do 10mbps full-duplex
233
LPA_100HALF                     equ     0x0080  ; Can do 100mbps half-duplex
234
LPA_100FULL                     equ     0x0100  ; Can do 100mbps full-duplex
235
LPA_100BASE4                    equ     0x0200  ; Can do 100mbps 4k packets
236
LPA_RESV                        equ     0x1c00  ; Unused...
237
LPA_RFAULT                      equ     0x2000  ; Link partner faulted
238
LPA_LPACK                       equ     0x4000  ; Link partner acked us
239
LPA_NPAGE                       equ     0x8000  ; Next page bit
866 shurf 240
 
2288 clevermous 241
MII_READ                        equ     (-1)
242
MII_PHYSID1                     equ     0x02    ; PHYS ID 1
243
MII_PHYSID2                     equ     0x03    ; PHYS ID 2
244
MII_BMCR                        equ     0x00    ; Basic mode control register
245
MII_BMSR                        equ     0x01    ; Basic mode status register
246
MII_ADVERTISE                   equ     0x04    ; Advertisement control reg
247
MII_LPA                         equ     0x05    ; Link partner ability reg
248
MII_SREVISION                   equ     0x16    ; Silicon revision
249
MII_RESV1                       equ     0x17    ; Reserved...
250
MII_NCONFIG                     equ     0x1c    ; Network interface config
866 shurf 251
 
252
; PHY defines
2288 clevermous 253
PHY_OUI_MARVELL                 equ     0x5043
254
PHY_OUI_CICADA                  equ     0x03f1
255
PHYID1_OUI_MASK                 equ     0x03ff
256
PHYID1_OUI_SHFT                 equ     6
257
PHYID2_OUI_MASK                 equ     0xfc00
258
PHYID2_OUI_SHFT                 equ     10
259
PHY_INIT1                       equ     0x0f000
260
PHY_INIT2                       equ     0x0e00
261
PHY_INIT3                       equ     0x01000
262
PHY_INIT4                       equ     0x0200
263
PHY_INIT5                       equ     0x0004
264
PHY_INIT6                       equ     0x02000
265
PHY_GIGABIT                     equ     0x0100
866 shurf 266
 
2288 clevermous 267
PHY_TIMEOUT                     equ     0x1
268
PHY_ERROR                       equ     0x2
866 shurf 269
 
2288 clevermous 270
PHY_100                         equ     0x1
271
PHY_1000                        equ     0x2
272
PHY_HALF                        equ     0x100
866 shurf 273
 
2288 clevermous 274
PHY_RGMII                       equ     0x10000000
866 shurf 275
 
276
; desc_ver values:
277
; This field has two purposes:
278
; - Newer nics uses a different ring layout. The layout is selected by
279
;   comparing np->desc_ver with DESC_VER_xy.
280
; - It contains bits that are forced on when writing to NvRegTxRxControl.
2288 clevermous 281
DESC_VER_1                      equ     0x0
282
DESC_VER_2                      equ     (0x02100 or NVREG_TXRXCTL_RXCHECK)
866 shurf 283
 
2288 clevermous 284
MAC_ADDR_LEN                    equ     6
866 shurf 285
 
2288 clevermous 286
NV_TX_LASTPACKET                equ     (1 shl 16)
287
NV_TX_RETRYERROR                equ     (1 shl 19)
288
NV_TX_LASTPACKET1               equ     (1 shl 24)
289
NV_TX_DEFERRED                  equ     (1 shl 26)
290
NV_TX_CARRIERLOST               equ     (1 shl 27)
291
NV_TX_LATECOLLISION             equ     (1 shl 28)
292
NV_TX_UNDERFLOW                 equ     (1 shl 29)
293
NV_TX_ERROR                     equ     (1 shl 30)
294
NV_TX_VALID                     equ     (1 shl 31)
866 shurf 295
 
2288 clevermous 296
NV_TX2_LASTPACKET               equ     (1 shl 29)
297
NV_TX2_RETRYERROR               equ     (1 shl 18)
298
NV_TX2_LASTPACKET1              equ     (1 shl 23)
299
NV_TX2_DEFERRED                 equ     (1 shl 25)
300
NV_TX2_CARRIERLOST              equ     (1 shl 26)
301
NV_TX2_LATECOLLISION            equ     (1 shl 27)
302
NV_TX2_UNDERFLOW                equ     (1 shl 28)
866 shurf 303
; error and valid are the same for both
2288 clevermous 304
NV_TX2_ERROR                    equ     (1 shl 30)
305
NV_TX2_VALID                    equ     (1 shl 31)
866 shurf 306
 
2288 clevermous 307
NV_RX_DESCRIPTORVALID           equ     (1 shl 16)
308
NV_RX_AVAIL                     equ     (1 shl 31)
866 shurf 309
 
2288 clevermous 310
NV_RX2_DESCRIPTORVALID          equ     (1 shl 29)
866 shurf 311
 
2288 clevermous 312
RX_RING                         equ     4
313
TX_RING                         equ     2
866 shurf 314
 
2288 clevermous 315
FLAG_MASK_V1                    equ     0xffff0000
316
FLAG_MASK_V2                    equ     0xffffc000
317
LEN_MASK_V1                     equ     (0xffffffff xor FLAG_MASK_V1)
318
LEN_MASK_V2                     equ     (0xffffffff xor FLAG_MASK_V2)
866 shurf 319
 
320
; Miscelaneous hardware related defines:
2288 clevermous 321
NV_PCI_REGSZ_VER1               equ     0x270
322
NV_PCI_REGSZ_VER2               equ     0x604
866 shurf 323
; various timeout delays: all in usec
2288 clevermous 324
NV_TXRX_RESET_DELAY             equ     4
325
NV_TXSTOP_DELAY1                equ     10
326
NV_TXSTOP_DELAY1MAX             equ     500000
327
NV_TXSTOP_DELAY2                equ     100
328
NV_RXSTOP_DELAY1                equ     10
329
NV_RXSTOP_DELAY1MAX             equ     500000
330
NV_RXSTOP_DELAY2                equ     100
331
NV_SETUP5_DELAY                 equ     5
332
NV_SETUP5_DELAYMAX              equ     50000
333
NV_POWERUP_DELAY                equ     5
334
NV_POWERUP_DELAYMAX             equ     5000
335
NV_MIIBUSY_DELAY                equ     50
336
NV_MIIPHY_DELAY                 equ     10
337
NV_MIIPHY_DELAYMAX              equ     10000
338
NV_MAC_RESET_DELAY              equ     64
339
NV_WAKEUPPATTERNS               equ     5
340
NV_WAKEUPMASKENTRIES            equ     4
866 shurf 341
 
342
; Advertisement control register.
2288 clevermous 343
ADVERTISE_SLCT                  equ     0x001f  ; Selector bits
344
ADVERTISE_CSMA                  equ     0x0001  ; Only selector supported
345
ADVERTISE_10HALF                equ     0x0020  ; Try for 10mbps half-duplex
346
ADVERTISE_10FULL                equ     0x0040  ; Try for 10mbps full-duplex
347
ADVERTISE_100HALF               equ     0x0080  ; Try for 100mbps half-duplex
348
ADVERTISE_100FULL               equ     0x0100  ; Try for 100mbps full-duplex
349
ADVERTISE_100BASE4              equ     0x0200  ; Try for 100mbps 4k packets
350
ADVERTISE_RESV                  equ     0x1c00  ; Unused...
351
ADVERTISE_RFAULT                equ     0x2000  ; Say we can detect faults
352
ADVERTISE_LPACK                 equ     0x4000  ; Ack link partners response
353
ADVERTISE_NPAGE                 equ     0x8000  ; Next page bit
866 shurf 354
 
2288 clevermous 355
ADVERTISE_FULL                  equ     (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA)
356
ADVERTISE_ALL                   equ     (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL)
866 shurf 357
 
2288 clevermous 358
MII_1000BT_CR                   equ     0x09
359
MII_1000BT_SR                   equ     0x0a
360
ADVERTISE_1000FULL              equ     0x0200
361
ADVERTISE_1000HALF              equ     0x0100
866 shurf 362
 
2288 clevermous 363
BMCR_ANRESTART                  equ     0x0200  ; Auto negotiation restart
364
BMCR_ANENABLE                   equ     0x1000  ; Enable auto negotiation
365
BMCR_SPEED100                   equ     0x2000  ; Select 100Mbps
366
BMCR_LOOPBACK                   equ     0x4000  ; TXD loopback bits
367
BMCR_RESET                      equ     0x8000  ; Reset the DP83840
866 shurf 368
 
369
; Basic mode status register.
2288 clevermous 370
BMSR_ERCAP                      equ     0x0001  ; Ext-reg capability
371
BMSR_JCD                        equ     0x0002  ; Jabber detected
372
BMSR_LSTATUS                    equ     0x0004  ; Link status
373
BMSR_ANEGCAPABLE                equ     0x0008  ; Able to do auto-negotiation
374
BMSR_RFAULT                     equ     0x0010  ; Remote fault detected
375
BMSR_ANEGCOMPLETE               equ     0x0020  ; Auto-negotiation complete
376
BMSR_RESV                       equ     0x07c0  ; Unused...
377
BMSR_10HALF                     equ     0x0800  ; Can do 10mbps, half-duplex
378
BMSR_10FULL                     equ     0x1000  ; Can do 10mbps, full-duplex
379
BMSR_100HALF                    equ     0x2000  ; Can do 100mbps, half-duplex
380
BMSR_100FULL                    equ     0x4000  ; Can do 100mbps, full-duplex
381
BMSR_100BASE4                   equ     0x8000  ; Can do 100mbps, 4k packets
866 shurf 382
 
2288 clevermous 383
ETH_ALEN                        equ     6
384
ETH_HLEN                        equ     (2 * ETH_ALEN + 2)
385
ETH_ZLEN                        equ     60      ; 60 + 4bytes auto payload for
386
                                                ; mininmum 64bytes frame length
866 shurf 387
 
388
uglobal
2288 clevermous 389
forcedeth_mmio_addr     dd 0    ; memory map physical address
390
forcedeth_mmio_size     dd 0    ; size of memory bar
391
forcedeth_vendor_id     dw 0    ; Vendor ID
392
forcedeth_device_id     dw 0    ; Device ID
393
forcedeth_orig_mac0     dd 0    ; MAC
394
forcedeth_orig_mac1     dd 0    ; MAC
395
forcedeth_mapio_addr    dd 0    ; mapped IO address
396
forcedeth_txflags       dd 0    ;
397
forcedeth_desc_ver      dd 0    ;
398
forcedeth_irqmask       dd 0    ; IRQ-mask
399
forcedeth_wolenabled    dd 0    ; WOL
400
forcedeth_in_shutdown   dd 0    ;
401
forcedeth_cur_rx        dd 0    ;
402
forcedeth_refill_rx     dd 0    ;
403
forcedeth_phyaddr       dd 0    ;
404
forcedeth_phy_oui       dd 0    ;
405
forcedeth_gigabit       dd 0    ;
406
forcedeth_needs_mac_reset dd 0  ;
407
forcedeth_linkspeed     dd 0    ;
408
forcedeth_duplex        dd 0    ;
409
forcedeth_next_tx       dd 0    ; next TX descriptor number
410
forcedeth_nic_tx        dd 0    ; ??? d'nt used ???
411
forcedeth_packetlen     dd 0    ;
412
forcedeth_nocable       dd 0    ; no cable present
866 shurf 413
endg
414
 
2288 clevermous 415
struc   forcedeth_TxDesc {
416
        .PacketBuffer   dd ?
417
        .FlagLen        dd ?
866 shurf 418
}
2288 clevermous 419
virtual at 0
420
        forcedeth_TxDesc forcedeth_TxDesc
421
        sizeof.forcedeth_TxDesc = $ - forcedeth_TxDesc
866 shurf 422
end virtual
423
 
2288 clevermous 424
struc   forcedeth_RxDesc {
425
        .PacketBuffer   dd ?
426
        .FlagLen        dd ?
866 shurf 427
}
2288 clevermous 428
virtual at 0
429
        forcedeth_RxDesc forcedeth_RxDesc
430
        sizeof.forcedeth_RxDesc = $ - forcedeth_RxDesc
866 shurf 431
end virtual
432
 
433
virtual at eth_data_start
2288 clevermous 434
        ; Define the TX Descriptor
435
        align   256
436
        forcedeth_tx_ring       rb      TX_RING * sizeof.forcedeth_TxDesc
437
        ; Create a static buffer of size RX_BUF_SZ for each
438
        ; TX Descriptor.  All descriptors point to a
439
        ; part of this buffer
440
        align   256
441
        forcedeth_txb   rb      TX_RING * RX_NIC_BUFSIZE
442
 
443
        ; Define the RX Descriptor
444
        align   256
445
        forcedeth_rx_ring       rb      RX_RING * sizeof.forcedeth_RxDesc
446
        ; Create a static buffer of size RX_BUF_SZ for each
447
        ; RX Descriptor.  All descriptors point to a
448
        ; part of this buffer
449
        align   256
450
        forcedeth_rxb   rb      RX_RING * RX_NIC_BUFSIZE
866 shurf 451
end virtual
452
 
453
 
454
;***************************************************************************
455
;   Function
456
;      forcedeth_reset
457
;   Description
458
;      Place the chip (ie, the ethernet card) into a virgin state
459
;      No inputs
460
;      All registers destroyed
461
;
462
;***************************************************************************
463
forcedeth_reset:
464
 
2288 clevermous 465
        ; 1) erase previous misconfiguration
466
        ; 4.1-1: stop adapter: ignored, 4.3 seems to be overkill
866 shurf 467
 
2288 clevermous 468
        ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA)
469
        mov     edi, dword [forcedeth_mapio_addr]
470
        mov     dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE
866 shurf 471
 
2288 clevermous 472
        ; writel(0, base + NvRegMulticastAddrB)
473
        mov     dword [edi+NvRegMulticastAddrB], 0
474
 
475
        ; writel(0, base + NvRegMulticastMaskA)
476
        mov     dword [edi+NvRegMulticastMaskA], 0
477
 
478
        ; writel(0, base + NvRegMulticastMaskB)
479
        mov     dword [edi+NvRegMulticastMaskB], 0
866 shurf 480
 
2288 clevermous 481
        ; writel(0, base + NvRegPacketFilterFlags)
482
        mov     dword [edi+NvRegPacketFilterFlags], 0
483
 
484
        ; writel(0, base + NvRegTransmitterControl)
485
        mov     dword [edi+NvRegTransmitterControl], 0
486
 
487
        ; writel(0, base + NvRegReceiverControl)
488
        mov     dword [edi+NvRegReceiverControl], 0
866 shurf 489
 
2288 clevermous 490
        ; writel(0, base + NvRegAdapterControl)
491
        mov     dword [edi+NvRegAdapterControl], 0
866 shurf 492
 
493
 
2288 clevermous 494
        ; 2) initialize descriptor rings
495
        ; init_ring(nic)
496
        call    forcedeth_init_ring
866 shurf 497
 
2288 clevermous 498
        ; writel(0, base + NvRegLinkSpeed)
499
        mov     dword [edi+NvRegLinkSpeed], 0
500
 
501
        ; writel(0, base + NvRegUnknownTransmitterReg)
502
        mov     dword [edi+NvRegUnknownTransmitterReg], 0
866 shurf 503
 
2288 clevermous 504
        ; txrx_reset(nic)
505
        call    forcedeth_txrx_reset
506
 
507
        ; writel(0, base + NvRegUnknownSetupReg6)
508
        mov     dword [edi+NvRegUnknownSetupReg6], 0
866 shurf 509
 
2288 clevermous 510
        ; np->in_shutdown = 0
511
        mov     dword [forcedeth_in_shutdown], 0
866 shurf 512
 
513
 
2288 clevermous 514
        ; 3) set mac address
515
        ; writel(mac[0], base + NvRegMacAddrA)
516
        mov     eax, dword [forcedeth_orig_mac0]
517
        mov     dword [edi+NvRegMacAddrA], eax
518
 
519
        ; writel(mac[1], base + NvRegMacAddrB)
520
        mov     eax, dword [forcedeth_orig_mac1]
521
        mov     dword [edi+NvRegMacAddrB], eax
866 shurf 522
 
523
 
2288 clevermous 524
        ; 4) give hw rings
525
        ; writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr)
526
        mov     eax, forcedeth_rx_ring
866 shurf 527
 
528
;DEBUGF 1," K : FORCEDETH: rx_ring at 0x%x\n", eax
529
 
2288 clevermous 530
        sub     eax, OS_BASE    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
531
        mov     dword [edi+NvRegRxRingPhysAddr], eax
866 shurf 532
 
2288 clevermous 533
        ; writel((u32) virt_to_le32desc(&tx_ring[0]), base + NvRegTxRingPhysAddr)
534
        mov     eax, forcedeth_tx_ring
535
        sub     eax, OS_BASE    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
536
        mov     dword [edi+NvRegTxRingPhysAddr], eax
866 shurf 537
 
2288 clevermous 538
        ; writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes)
539
        mov     dword [edi+NvRegRingSizes], (((RX_RING - 1) shl NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) shl NVREG_RINGSZ_TXSHIFT))
866 shurf 540
 
2288 clevermous 541
        ; 5) continue setup
542
        ; np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
543
        mov     dword [forcedeth_linkspeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
544
 
545
        ; np->duplex = 0
546
        mov     dword [forcedeth_duplex], 0
866 shurf 547
 
2288 clevermous 548
        ; writel(np->linkspeed, base + NvRegLinkSpeed)
549
        mov     dword [edi+NvRegLinkSpeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
866 shurf 550
 
2288 clevermous 551
        ; writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3)
552
        mov     dword [edi+NvRegUnknownSetupReg3], NVREG_UNKSETUP3_VAL1
553
 
554
        ; writel(np->desc_ver, base + NvRegTxRxControl)
555
        mov     eax, dword [forcedeth_desc_ver]
556
        mov     dword [edi+NvRegTxRxControl], eax
557
 
558
        ; pci_push(base)
559
        call    forcedeth_pci_push
560
 
561
        ; writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl)
562
        or      eax, NVREG_TXRXCTL_BIT1
563
        mov     dword [edi+NvRegTxRxControl], eax
866 shurf 564
 
2288 clevermous 565
        ; reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, "open: SetupReg5, Bit 31 remained off\n")
566
        push    ebx edx edi     ;;;;;;;;;;;;;;;;;;;;;;
567
        stdcall forcedeth_reg_delay, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, 0
568
        pop     edi edx ebx     ;;;;;;;;;;;;;;;;;;;;;;
866 shurf 569
 
2288 clevermous 570
        ; writel(0, base + NvRegUnknownSetupReg4)
571
        mov     dword [edi+NvRegUnknownSetupReg4], 0
866 shurf 572
 
2288 clevermous 573
        ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus)
574
        mov     dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2
575
 
866 shurf 576
 
2288 clevermous 577
        ; printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half")
866 shurf 578
;;;;;;;;;;; DEBUGF
579
 
2288 clevermous 580
        ; 6) continue setup
581
 
582
        ; writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1)
583
        mov     dword [edi+NvRegMisc1], (NVREG_MISC1_FORCE or NVREG_MISC1_HD)
584
 
585
        ; writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus)
586
        mov     eax, dword [edi+NvRegTransmitterStatus]
587
        mov     dword [edi+NvRegTransmitterStatus], eax
866 shurf 588
 
2288 clevermous 589
        ; writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags)
590
        mov     dword [edi+NvRegPacketFilterFlags], NVREG_PFF_ALWAYS
866 shurf 591
 
2288 clevermous 592
        ; writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig)
593
        mov     dword [edi+NvRegOffloadConfig], NVREG_OFFLOAD_NORMAL
866 shurf 594
 
2288 clevermous 595
        ; writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus)
596
        mov     eax, dword [edi+NvRegReceiverStatus]
597
        mov     dword [edi+NvRegReceiverStatus], eax
866 shurf 598
 
2288 clevermous 599
        ; Get a random number
600
        ; i = random()
601
        push    edi
602
        stdcall sys_clock       ; eax = 0x00SSMMHH (current system time)
603
        pop     edi
866 shurf 604
 
2288 clevermous 605
        ; writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK), base + NvRegRandomSeed)
606
        and     eax, NVREG_RNDSEED_MASK
607
        or      eax, NVREG_RNDSEED_FORCE
608
        mov     dword [edi+NvRegRandomSeed], eax
866 shurf 609
 
2288 clevermous 610
        ; writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1)
611
        mov     dword [edi+NvRegUnknownSetupReg1], NVREG_UNKSETUP1_VAL
612
 
613
        ; writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2)
614
        mov     dword [edi+NvRegUnknownSetupReg2], NVREG_UNKSETUP2_VAL
615
 
616
        ; writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval)
617
        mov     dword [edi+NvRegPollingInterval], NVREG_POLL_DEFAULT
618
 
619
        ; writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6)
620
        mov     dword [edi+NvRegUnknownSetupReg6], NVREG_UNKSETUP6_VAL
866 shurf 621
 
2288 clevermous 622
        ; writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING,
623
        ; base + NvRegAdapterControl)
624
        mov     eax, dword [forcedeth_phyaddr]
625
        shl     eax, NVREG_ADAPTCTL_PHYSHIFT
626
        or      eax, (NVREG_ADAPTCTL_PHYVALID or NVREG_ADAPTCTL_RUNNING)
627
        mov     dword [edi+NvRegAdapterControl], eax
628
 
629
        ; writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed)
630
        mov     dword [edi+NvRegMIISpeed], (NVREG_MIISPEED_BIT8 or NVREG_MIIDELAY)
866 shurf 631
 
2288 clevermous 632
        ; writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4)
633
        mov     dword [edi+NvRegUnknownSetupReg4], NVREG_UNKSETUP4_VAL
866 shurf 634
 
2288 clevermous 635
        ; writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags)
636
        mov     dword [edi+NvRegWakeUpFlags], NVREG_WAKEUPFLAGS_VAL
637
 
638
        ; i = readl(base + NvRegPowerState)
639
        mov     eax, dword [edi+NvRegPowerState]
866 shurf 640
 
2288 clevermous 641
        ; if ((i & NVREG_POWERSTATE_POWEREDUP) == 0)
642
        test    eax, NVREG_POWERSTATE_POWEREDUP
643
        jnz     @f
644
        ; writel(NVREG_POWERSTATE_POWEREDUP | i, base + NvRegPowerState)
645
        or      eax, NVREG_POWERSTATE_POWEREDUP
646
        mov     dword [edi+NvRegPowerState], eax
866 shurf 647
 
648
@@:
649
 
2288 clevermous 650
        ; pci_push(base)
651
        call    forcedeth_pci_push
866 shurf 652
 
2288 clevermous 653
        ; nv_udelay(10)
654
        mov     esi, 10
655
        call    forcedeth_nv_udelay
866 shurf 656
 
2288 clevermous 657
        ; writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState)
658
        mov     eax, dword [edi+NvRegPowerState]
659
        or      eax, NVREG_POWERSTATE_VALID
660
        mov     dword [edi+NvRegPowerState], eax
866 shurf 661
 
2288 clevermous 662
        ; ??? disable all interrupts ???
663
        ; writel(0, base + NvRegIrqMask)
664
        mov     dword [edi+NvRegIrqMask], 0
866 shurf 665
 
2288 clevermous 666
;;;     ; ??? Mask RX interrupts
667
;;;     mov     dword [edi+NvRegIrqMask], NVREG_IRQ_RX_ALL
668
;;;     ; ??? Mask TX interrupts
669
;;;     ;mov    dword [edi+NvRegIrqMask], NVREG_IRQ_TX_ALL
670
;;;     ; ??? Mask OTHER interrupts
671
;;;     mov     dword [edi+NvRegIrqMask], NVREG_IRQ_OTHER_ALL
672
 
673
        ; pci_push(base)
674
        call    forcedeth_pci_push
866 shurf 675
 
2288 clevermous 676
        ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus)
677
        mov     dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2
866 shurf 678
 
2288 clevermous 679
        ; writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus)
680
        mov     dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK
866 shurf 681
 
2288 clevermous 682
        ; pci_push(base)
683
        call    forcedeth_pci_push
866 shurf 684
 
685
 
2288 clevermous 686
        ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA)
687
        mov     dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE
866 shurf 688
 
2288 clevermous 689
        ; writel(0, base + NvRegMulticastAddrB)
690
        mov     dword [edi+NvRegMulticastAddrB], 0
866 shurf 691
 
2288 clevermous 692
        ; writel(0, base + NvRegMulticastMaskA)
693
        mov     dword [edi+NvRegMulticastMaskA], 0
866 shurf 694
 
2288 clevermous 695
        ; writel(0, base + NvRegMulticastMaskB)
696
        mov     dword [edi+NvRegMulticastMaskB], 0
866 shurf 697
 
2288 clevermous 698
        ; writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags)
699
        mov     dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_ALWAYS or NVREG_PFF_MYADDR)
866 shurf 700
 
2288 clevermous 701
        ; set_multicast(nic)
702
        call    forcedeth_set_multicast
703
 
704
        ; One manual link speed update: Interrupts are enabled, future link
705
        ; speed changes cause interrupts and are handled by nv_link_irq().
866 shurf 706
 
2288 clevermous 707
        ; miistat = readl(base + NvRegMIIStatus)
708
        mov     eax, dword [edi+NvRegMIIStatus]
866 shurf 709
 
2288 clevermous 710
        ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
711
        mov     dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK
866 shurf 712
 
2288 clevermous 713
        ; dprintf(("startup: got 0x%hX.\n", miistat));
714
;;;     DEBUGF 1," K : FORCEDETH: startup: got 0x%x\n", eax
866 shurf 715
 
716
 
2288 clevermous 717
        ; ret = update_linkspeed(nic)
718
        call    forcedeth_update_linkspeed
719
        push    eax
866 shurf 720
 
2288 clevermous 721
        ; start_tx(nic)
722
        call    forcedeth_start_tx
866 shurf 723
 
2288 clevermous 724
        pop     eax
866 shurf 725
 
726
;        if (ret) {
727
;                //Start Connection netif_carrier_on(dev);
728
;        } else {
729
;                printf("no link during initialization.\n");
730
;        }
731
 
2288 clevermous 732
        ;*** added by shurf (21.09.2008)
733
        mov     dword [forcedeth_nocable], 0
734
        ;***
866 shurf 735
 
2288 clevermous 736
        test    eax, eax
737
        jnz     .return
738
        DEBUGF 1," K : FORCEDETH: no link during initialization.\n"
866 shurf 739
 
2288 clevermous 740
        ;*** added by shurf (21.09.2008)
741
        mov     dword [forcedeth_nocable], 1
742
        ;***
866 shurf 743
 
744
.return:
745
 
746
; Indicate that we have successfully reset the card
747
        mov     eax, dword [pci_data]
748
        mov     dword [eth_status], eax
2288 clevermous 749
        ret
750
 
866 shurf 751
 
752
 
753
;***************************************************************************
754
;   Function
755
;      forcedeth_probe
756
;   Description
757
;      Searches for an ethernet card, enables it and clears the rx buffer
758
;      If a card was found, it enables the ethernet -> TCPIP link
759
;
760
;***************************************************************************
761
forcedeth_probe:
762
 
2288 clevermous 763
;       DEBUGF 1," K : FORCEDETH: 0x%x 0x%x, 0x%x\n", [io_addr]:8,[pci_bus]:2,[pci_dev]:2
866 shurf 764
 
2288 clevermous 765
        mov     dword [forcedeth_needs_mac_reset], 0
866 shurf 766
 
767
; BEGIN of adjust_pci_device()
2288 clevermous 768
        ; read word from PCI-device
769
        mov     al, 1   ;;;;;;;;;;;;;;2
770
        mov     bh, [pci_dev]
771
        mov     ah, [pci_bus]
772
        mov     bl, PCI_REG_COMMAND
773
        call    pci_read_reg
774
        mov     bx, ax                  ; new command
775
        or      bx, PCI_COMMAND_MASTER
776
        or      bx, PCI_COMMAND_IO
777
        cmp     bx, ax
778
        je      @f
779
        ; Enabling PCI-device (make card as bus master)
780
        DEBUGF 1," K : FORCEDETH: Updating PCI command 0x%x->0x%x\n", ax, bx
781
        mov     cx, bx
782
        mov     al, 1   ;;;;;;;;;;;;2
783
        mov     bh, [pci_dev]
784
        mov     ah, [pci_bus]
785
        mov     bl, PCI_REG_COMMAND
786
        call    pci_write_reg
866 shurf 787
 
2288 clevermous 788
        ; Check latency settings
866 shurf 789
@@:
2288 clevermous 790
        ; Get current latency settings from Latency timer register (byte)
791
        mov     al, 0   ;;;;;;;;;1
792
        mov     bh, [pci_dev]
793
        mov     ah, [pci_bus]
794
        mov     bl, PCI_LATENCY_TIMER
795
        call    pci_read_reg
866 shurf 796
 
2288 clevermous 797
        ; see if its at least 32
798
        cmp     al, 32
799
        jge     @f
800
        ; set latency to 32
866 shurf 801
        DEBUGF 1, "K : FORCEDETH: PCI latency timer (CFLT) is unreasonably low at %d.\n", al
802
        DEBUGF 1, "K : FORCEDETH: Setting to 32 clocks.\n"
2288 clevermous 803
        mov     cl, 32
804
        mov     al, 0   ;;;;;;;1
805
        mov     bh, [pci_dev]
806
        mov     ah, [pci_bus]
807
        mov     bl, PCI_LATENCY_TIMER
808
        call    pci_write_reg
866 shurf 809
; END of adjust_pci_device()
810
 
811
@@:
812
; BEGIN of pci_bar_start (addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0))
2288 clevermous 813
        mov     al, 2   ; dword
814
        mov     bh, [pci_dev]
815
        mov     ah, [pci_bus]
816
        mov     bl, PCI_BASE_ADDRESS_0
817
        call    pci_read_reg
818
        test    eax, PCI_BASE_ADDRESS_SPACE_IO
819
        jz      @f
820
        and     eax, PCI_BASE_ADDRESS_IO_MASK
821
        jmp     .next
822
@@:
823
        push    eax
824
        and     eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK
825
        cmp     eax, PCI_BASE_ADDRESS_MEM_TYPE_64
826
        jne     .not64
827
        mov     al, 2   ; dword
828
        mov     bh, [pci_dev]
829
        mov     ah, [pci_bus]
830
        mov     bl, PCI_BASE_ADDRESS_0 + 4
831
        call    pci_read_reg
832
        or      eax, eax
833
        jz      .not64
834
        DEBUGF  1,"K : FORCEDETH: pci_bar_start: Unhandled 64bit BAR\n"
835
        or      eax, -1
836
        jmp     .next
837
.not64:
838
        pop     eax
839
        and     eax, PCI_BASE_ADDRESS_MEM_MASK
866 shurf 840
.next:
841
; END of pci_bar_start
842
; addr = eax
2288 clevermous 843
        mov     dword [forcedeth_mmio_addr], eax
866 shurf 844
 
2288 clevermous 845
 
866 shurf 846
; BEGIN of pci_bar_size (sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0))
847
 
2288 clevermous 848
        ; Save original bar
849
        mov     al, 2   ; dword
850
        mov     bh, [pci_dev]
851
        mov     ah, [pci_bus]
852
        mov     bl, PCI_BASE_ADDRESS_0
853
        call    pci_read_reg
854
        mov     dword [forcedeth_tmp_start], eax
855
        ; Compute which bits can be set
856
        ; (ecx - value to write)
857
        mov     al, 2   ; dword
858
        mov     bh, [pci_dev]
859
        mov     ah, [pci_bus]
860
        mov     bl, PCI_BASE_ADDRESS_0
861
        mov     ecx, (not 0)
862
        call    pci_write_reg
863
        mov     al, 2   ; dword
864
        mov     bh, [pci_dev]
865
        mov     ah, [pci_bus]
866
        mov     bl, PCI_BASE_ADDRESS_0
867
        call    pci_read_reg
868
        push    eax
869
        ; Restore the original size
870
        mov     al, 2   ; dword
871
        mov     bh, [pci_dev]
872
        mov     ah, [pci_bus]
873
        mov     bl, PCI_BASE_ADDRESS_0
874
        mov     ecx, dword [forcedeth_tmp_start]
875
        call    pci_write_reg
876
        ; Find the significant bits
877
        pop     eax
878
        test    dword [forcedeth_tmp_start], PCI_BASE_ADDRESS_SPACE_IO
879
        jz      @f
880
        and     eax, PCI_BASE_ADDRESS_IO_MASK
881
        jmp     .next2
882
@@:
883
        and     eax, PCI_BASE_ADDRESS_MEM_MASK
866 shurf 884
.next2:
2288 clevermous 885
        ; Find the lowest bit set
886
        mov     ecx, eax
887
        sub     eax, 1
888
        not     eax
889
        and     ecx, eax
866 shurf 890
 
891
; END of pci_bar_start
2288 clevermous 892
        mov     dword [forcedeth_mmio_size], ecx
866 shurf 893
 
2288 clevermous 894
        DEBUGF 1," K : FORCEDETH: mmio_addr= 0x%x [mmio_size= 0x%x]\n", [forcedeth_mmio_addr]:8, [forcedeth_mmio_size]:8
866 shurf 895
 
2288 clevermous 896
        ; Get Vendor and Device ID
897
        mov     al, 2
898
        mov     bh, [pci_dev]
899
        mov     ah, [pci_bus]
900
        mov     bl, PCI_VENDOR_ID
901
        call    pci_read_reg
902
        mov     word [forcedeth_vendor_id], ax
903
        shr     eax, 16
904
        mov     word [forcedeth_device_id], ax
866 shurf 905
 
2288 clevermous 906
        DEBUGF 1," K : FORCEDETH: vendor_id= 0x%x device_id= 0x%x\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4
866 shurf 907
 
2288 clevermous 908
        ; handle different descriptor versions
909
        mov     eax, dword [forcedeth_device_id]
910
        cmp     eax, PCI_DEVICE_ID_NVIDIA_NVENET_1
911
        je      .ver1
912
        cmp     eax, PCI_DEVICE_ID_NVIDIA_NVENET_2
913
        je      .ver1
914
        cmp     eax, PCI_DEVICE_ID_NVIDIA_NVENET_3
915
        je      .ver1
916
        mov     dword [forcedeth_desc_ver], DESC_VER_2
917
        jmp     @f
918
.ver1:
919
        mov     dword [forcedeth_desc_ver], DESC_VER_1
866 shurf 920
@@:
2288 clevermous 921
        ; read the mac address
922
        ; map memory
923
        stdcall map_io_mem, [forcedeth_mmio_addr], [forcedeth_mmio_size], (PG_SW+PG_NOCACHE)
924
        test    eax, eax
925
        jz      .fail
866 shurf 926
 
2288 clevermous 927
        mov     dword [forcedeth_mapio_addr], eax
928
        mov     edi, eax
929
        mov     eax, dword [edi+NvRegMacAddrA]
930
        mov     dword [forcedeth_orig_mac0], eax
931
        mov     edx, dword [edi+NvRegMacAddrB]
932
        mov     dword [forcedeth_orig_mac1], edx
866 shurf 933
 
2288 clevermous 934
        ; save MAC-address to global variable node_addr
935
        mov     dword [node_addr], eax
936
        mov     word [node_addr+4], dx
866 shurf 937
 
2288 clevermous 938
        ; reverse if desired
939
        cmp     word [forcedeth_device_id], 0x03E5
940
        jae     .no_reverse_mac
941
        mov     al, byte [node_addr]
942
        xchg    al, byte [node_addr+5]
943
        mov     byte [node_addr], al
944
        mov     al, byte [node_addr+1]
945
        xchg    al, byte [node_addr+4]
946
        mov     byte [node_addr+4], al
947
        mov     al, byte [node_addr+2]
948
        xchg    al, byte [node_addr+3]
949
        mov     byte [node_addr+3], al
1194 clevermous 950
.no_reverse_mac:
951
 
2288 clevermous 952
;       DEBUGF 1," K : FORCEDETH: orig_mac0= 0x%x\n", [forcedeth_orig_mac0]:8
953
;       DEBUGF 1," K : FORCEDETH: orig_mac1= 0x%x\n", [forcedeth_orig_mac1]:8
954
        DEBUGF 1," K : FORCEDETH: 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,
866 shurf 955
 
2288 clevermous 956
        ; disable WOL
957
        mov     edi, dword [forcedeth_mapio_addr]
958
        mov     dword [edi+NvRegWakeUpFlags], 0
959
        mov     dword [forcedeth_wolenabled], 0
960
 
961
        mov     dword [forcedeth_txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID)
962
        cmp     dword [forcedeth_desc_ver], DESC_VER_1
963
        jne     @f
964
        mov     dword [forcedeth_txflags], (NV_TX_LASTPACKET or NV_TX_VALID)
965
@@:
866 shurf 966
 
967
; BEGIN of switch (pci->dev_id)
968
 
2288 clevermous 969
        cmp     word [forcedeth_device_id], 0x01C3
970
        jne     .next_0x0066
971
        ; nforce
972
        mov     dword [forcedeth_irqmask], 0    ;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
973
        jmp     .end_switch
866 shurf 974
 
975
.next_0x0066:
2288 clevermous 976
        cmp     word [forcedeth_device_id], 0x0066
977
        je      @f
978
        cmp     word [forcedeth_device_id], 0x00D6
979
        je      @f
980
        jmp     .next_0x0086
981
@@:
982
        mov     dword [forcedeth_irqmask], 0    ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
983
        cmp     dword [forcedeth_desc_ver], DESC_VER_1
984
        jne     @f
985
        or      dword [forcedeth_txflags], NV_TX_LASTPACKET1
986
        jmp     .end_switch
987
@@:
988
        or      dword [forcedeth_txflags], NV_TX2_LASTPACKET1
989
        jmp     .end_switch
866 shurf 990
 
991
.next_0x0086:
2288 clevermous 992
        cmp     word [forcedeth_device_id], 0x0086
993
        je      @f
994
        cmp     word [forcedeth_device_id], 0x008c
995
        je      @f
996
        cmp     word [forcedeth_device_id], 0x00e6
997
        je      @f
998
        cmp     word [forcedeth_device_id], 0x00df
999
        je      @f
1000
        cmp     word [forcedeth_device_id], 0x0056
1001
        je      @f
1002
        cmp     word [forcedeth_device_id], 0x0057
1003
        je      @f
1004
        cmp     word [forcedeth_device_id], 0x0037
1005
        je      @f
1006
        cmp     word [forcedeth_device_id], 0x0038
1007
        je      @f
1008
        jmp     .next_0x0268
1009
@@:
1010
        ; np->irqmask = NVREG_IRQMASK_WANTED_2;
1011
        ; np->irqmask |= NVREG_IRQ_TIMER;
1012
        mov     dword [forcedeth_irqmask], 0    ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
866 shurf 1013
 
2288 clevermous 1014
        ; if (np->desc_ver == DESC_VER_1)
1015
        cmp     dword [forcedeth_desc_ver], DESC_VER_1
1016
        jne     @f
1017
        ;  np->tx_flags |= NV_TX_LASTPACKET1;
1018
        or      dword [forcedeth_txflags], NV_TX_LASTPACKET1
1019
        jmp     .end_switch
1020
        ; else
866 shurf 1021
@@:
2288 clevermous 1022
        ;  np->tx_flags |= NV_TX2_LASTPACKET1;
1023
        or      dword [forcedeth_txflags], NV_TX2_LASTPACKET1
866 shurf 1024
 
2288 clevermous 1025
        ; break;
1026
        jmp     .end_switch
866 shurf 1027
 
1028
.next_0x0268:
2288 clevermous 1029
;       cmp     word [forcedeth_device_id], 0x0268
1030
;       je      @f
1031
;       cmp     word [forcedeth_device_id], 0x0269
1032
;       je      @f
1033
;       cmp     word [forcedeth_device_id], 0x0372
1034
;       je      @f
1035
;       cmp     word [forcedeth_device_id], 0x0373
1036
;       je      @f
1037
;       jmp     .default_switch
1194 clevermous 1038
;@@:
2288 clevermous 1039
        cmp     word [forcedeth_device_id], 0x0268
1040
        jb      .default_switch
1041
        ; pci_read_config_byte(pci, PCI_REVISION_ID, &revision_id);
1042
        mov     al, 0   ; byte
1043
        mov     bh, [pci_dev]
1044
        mov     ah, [pci_bus]
1045
        mov     bl, PCI_REVISION_ID
1046
        call    pci_read_reg
1047
        mov     ecx, eax        ; cl = revision_id
866 shurf 1048
 
2288 clevermous 1049
        ; take phy and nic out of low power mode
1050
        ; powerstate = readl(base + NvRegPowerState2);
1051
        mov     edi, dword [forcedeth_mapio_addr]
1052
        mov     eax, dword [edi+NvRegPowerState2]       ; eax = powerstate
1053
 
1054
        ; powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK;
1055
        and     eax, not NVREG_POWERSTATE2_POWERUP_MASK
1056
 
1057
        ; if ((pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_12||pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_13)&&revision_id>=0xA3)
1058
        cmp     dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12
1059
        je      @f
1060
        cmp     dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13
1061
        je      @f
1062
        jmp     .end_if
866 shurf 1063
@@:
2288 clevermous 1064
        cmp     cl, 0xA3
1065
        jl      .end_if
1066
        ;     powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3;
1067
        or      eax, NVREG_POWERSTATE2_POWERUP_REV_A3
866 shurf 1068
 
1069
.end_if:
1070
 
2288 clevermous 1071
        ; writel(powerstate, base + NvRegPowerState2);
1072
        mov     dword [edi+NvRegPowerState2], eax
866 shurf 1073
 
2288 clevermous 1074
        ; //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ
1075
        ; np->irqmask = NVREG_IRQMASK_WANTED_2;
1076
        ; np->irqmask |= NVREG_IRQ_TIMER;
1077
        mov     dword [forcedeth_irqmask], 0    ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
1078
 
1079
        ; needs_mac_reset = 1;
1080
        mov     dword [forcedeth_needs_mac_reset], 1
1081
 
1082
        ; if (np->desc_ver == DESC_VER_1)
1083
        cmp     dword [forcedeth_desc_ver], DESC_VER_1
1084
        jne     @f
1085
        ;   np->tx_flags |= NV_TX_LASTPACKET1;
1086
        or      dword [forcedeth_txflags], NV_TX_LASTPACKET1
1087
        jmp     .end_if2
866 shurf 1088
@@:
2288 clevermous 1089
        ; else
1090
        ;   np->tx_flags |= NV_TX2_LASTPACKET1;
1091
        or      dword [forcedeth_txflags], NV_TX2_LASTPACKET1
866 shurf 1092
 
1093
.end_if2:
2288 clevermous 1094
        ; break;
1095
        jmp     .end_switch
866 shurf 1096
 
1097
.default_switch:
2288 clevermous 1098
        DEBUGF 1," K : FORCEDETH: Your card was undefined in this driver.\n"
1099
        DEBUGF 1," K : FORCEDETH: Review driver_data in Kolibri driver and send a patch\n"
866 shurf 1100
 
1101
.end_switch:
1102
 
1103
; END of switch (pci->dev_id)
1104
 
1105
 
2288 clevermous 1106
        ; Find a suitable phy
1107
        mov     dword [forcedeth_tmp_i], 1
866 shurf 1108
.for_loop:
2288 clevermous 1109
        ; for (i = 1; i <= 32; i++)
1110
        ; phyaddr = i & 0x1f
1111
        mov     ebx, dword [forcedeth_tmp_i]
1112
        and     ebx, 0x1f
866 shurf 1113
 
2288 clevermous 1114
        ; id1 = mii_rw(phyaddr, MII_PHYSID1, MII_READ)
866 shurf 1115
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1116
        mov     eax, MII_PHYSID1
1117
        mov     ecx, MII_READ
1118
        call    forcedeth_mii_rw        ; id1 = eax
866 shurf 1119
 
2288 clevermous 1120
        ; if (id1 < 0 || id1 == 0xffff)
1121
        cmp     eax, 0xffffffff
1122
        je      .continue_for
1123
        test    eax, 0x80000000
1124
        jnz     .continue_for
1125
        mov     dword [forcedeth_tmp_id1], eax
866 shurf 1126
 
2288 clevermous 1127
        ; id2 = mii_rw(nic, phyaddr, MII_PHYSID2, MII_READ)
1128
        mov     eax, MII_PHYSID2
1129
        mov     ecx, MII_READ
1130
        call    forcedeth_mii_rw        ; id2 = eax
866 shurf 1131
 
2288 clevermous 1132
        ; if (id2 < 0 || id2 == 0xffff)
1133
        cmp     eax, 0xffffffff
1134
        je      .continue_for
1135
        test    eax, 0x80000000
1136
        jnz     .continue_for
1137
        mov     dword [forcedeth_tmp_id2], eax
866 shurf 1138
 
2288 clevermous 1139
        jmp     .break_for
866 shurf 1140
.continue_for:
2288 clevermous 1141
        inc     dword [forcedeth_tmp_i]
1142
        cmp     dword [forcedeth_tmp_i], 32
1143
        jle     .for_loop
1144
        jmp     .end_for
866 shurf 1145
 
1146
.break_for:
1147
 
2288 clevermous 1148
;;;;    DEBUGF 1," K : FORCEDETH: id1=0x%x id2=0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8
866 shurf 1149
 
2288 clevermous 1150
        ; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT
1151
        mov     eax, dword [forcedeth_tmp_id1]
1152
        and     eax, PHYID1_OUI_MASK
1153
        shl     eax, PHYID1_OUI_SHFT
1154
        mov     dword [forcedeth_tmp_id1], eax
866 shurf 1155
 
2288 clevermous 1156
        ; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT
1157
        mov     eax, dword [forcedeth_tmp_id2]
1158
        and     eax, PHYID2_OUI_MASK
1159
        shr     eax, PHYID2_OUI_SHFT
1160
        mov     dword [forcedeth_tmp_id2], eax
866 shurf 1161
 
2288 clevermous 1162
        DEBUGF 1," K : FORCEDETH: Found PHY  0x%x:0x%x at address 0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8, ebx
866 shurf 1163
 
2288 clevermous 1164
        ; np->phyaddr = phyaddr;
1165
        mov     dword [forcedeth_phyaddr], ebx
866 shurf 1166
 
2288 clevermous 1167
        ; np->phy_oui = id1 | id2;
1168
        mov     eax, dword [forcedeth_tmp_id1]
1169
        or      eax, dword [forcedeth_tmp_id2]
1170
        mov     dword [forcedeth_phy_oui], eax
866 shurf 1171
 
1172
.end_for:
1173
 
2288 clevermous 1174
        ; if (i == 33)
1175
        cmp     dword [forcedeth_tmp_i], 33
1176
        jne     @f
1177
        ; PHY in isolate mode? No phy attached and user wants to
1178
        ; test loopback? Very odd, but can be correct.
1179
 
1180
        DEBUGF 1," K : FORCEDETH: Could not find a valid PHY.\n"
866 shurf 1181
 
2288 clevermous 1182
        jmp     .next3
866 shurf 1183
 
1184
@@:
1185
 
2288 clevermous 1186
        ; if (i != 33)
1187
        ; reset it
1188
        call    forcedeth_phy_init
866 shurf 1189
 
1190
.next3:
1191
 
1192
;        dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n",
1193
;                 pci->name, pci->vendor, pci->dev_id, pci->name));
2288 clevermous 1194
        DEBUGF 1," K : FORCEDETH: subsystem: 0x%x:0x%x bound to forcedeth\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4
866 shurf 1195
 
1196
 
1197
;        if(needs_mac_reset) mac_reset(nic);
2288 clevermous 1198
        cmp     dword [forcedeth_needs_mac_reset], 0
1199
        je      @f
1200
        call    forcedeth_mac_reset
866 shurf 1201
 
1202
@@:
2288 clevermous 1203
 
1204
        ; if(!forcedeth_reset(nic)) return 0; // no valid link
1205
        call    forcedeth_reset
1206
        test    eax, eax
1207
        jnz     @f
1208
        mov     eax, 0
1209
        jmp     .return
866 shurf 1210
 
1211
@@:
1212
 
2288 clevermous 1213
        ; point to NIC specific routines
1214
        ; dev->disable = forcedeth_disable;
1215
        ; nic->poll = forcedeth_poll;
1216
        ; nic->transmit = forcedeth_transmit;
1217
        ; nic->irq = forcedeth_irq;
1218
        ;;;;;;;;;stdcall attach_int_handler, 11, forcedeth_int_handler, 0
866 shurf 1219
 
2288 clevermous 1220
        ; return 1
1221
        mov     eax, 1
1222
        jmp     .return
866 shurf 1223
 
1224
.fail:
2288 clevermous 1225
        mov     eax, 0
866 shurf 1226
 
1227
.return:
2288 clevermous 1228
        ret
866 shurf 1229
 
1230
uglobal
2288 clevermous 1231
forcedeth_tmp_start     dd ?
1232
forcedeth_tmp_reg       dd ?
1233
forcedeth_tmp_i         dd ?
1234
forcedeth_tmp_id1       dd ?
1235
forcedeth_tmp_id2       dd ?
1236
forcedeth_tmp_phyinterface      dd ?
1237
forcedeth_tmp_newls     dd ?
1238
forcedeth_tmp_newdup    dd ?
1239
forcedeth_tmp_retval    dd ?
1240
forcedeth_tmp_control_1000      dd ?
1241
forcedeth_tmp_lpa       dd ?
1242
forcedeth_tmp_adv       dd ?
1243
forcedeth_tmp_len       dd ?
1244
forcedeth_tmp_valid     dd ?
1245
forcedeth_tmp_nr        dd ?
1246
forcedeth_tmp_ptxb      dd ?
866 shurf 1247
endg
1248
 
1249
;***************************************************************************
1250
; Function
1251
;    forcedeth_poll
1252
;
1253
; Description
1254
;    Polls the ethernet card for a received packet
1255
;    Received data, if any, ends up in Ether_buffer
1256
;
1257
;***************************************************************************
1258
forcedeth_poll:
1259
 
2288 clevermous 1260
        mov     word [eth_rx_data_len], 0
866 shurf 1261
 
2288 clevermous 1262
        ; ????????????????????????????
1263
        ; ??? Clear events? ???
1264
        mov     edi, dword [forcedeth_mapio_addr]
1265
        mov     dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK
1266
        ; ????????????????????????????
866 shurf 1267
 
1268
.top:
1269
 
2288 clevermous 1270
        ; i = np->cur_rx % RX_RING
1271
        mov     eax, dword [forcedeth_cur_rx]
1272
        and     eax, (RX_RING-1)
1273
        mov     dword [forcedeth_tmp_i], eax
866 shurf 1274
 
2288 clevermous 1275
        ; Flags = le32_to_cpu(rx_ring[i].FlagLen)
1276
        ; Flags = rx_ring[i].FlagLen
1277
        mov     cl, sizeof.forcedeth_RxDesc
1278
        mul     cl
1279
        add     eax, forcedeth_rx_ring
1280
        mov     ebx, eax
1281
        mov     eax, [ebx + forcedeth_RxDesc.FlagLen]
866 shurf 1282
 
1283
 
2288 clevermous 1284
        ; if (Flags & NV_RX_AVAIL)
1285
        test    eax, NV_RX_AVAIL
1286
        ;   return 0;       /* still owned by hardware, */
1287
        ; still owned by hardware
1288
        jnz     .return0
866 shurf 1289
 
2288 clevermous 1290
;;;;;   DEBUGF  1,"poll: FlagLen = %x\n", eax
866 shurf 1291
 
2288 clevermous 1292
        ; if (np->desc_ver == DESC_VER_1) {
1293
        cmp     dword [forcedeth_desc_ver], DESC_VER_1
1294
        jne     @f
1295
        ;   if (!(Flags & NV_RX_DESCRIPTORVALID))
1296
        test    eax, NV_RX_DESCRIPTORVALID
1297
        ;     return 0;
1298
        jz      .return0
1299
        jmp     .next
1300
        ; } else {
866 shurf 1301
@@:
2288 clevermous 1302
        ;   if (!(Flags & NV_RX2_DESCRIPTORVALID))
1303
        test    eax, NV_RX2_DESCRIPTORVALID
1304
        ;     return 0;
1305
        jz      .return0
1306
        ; }
1307
 
866 shurf 1308
.next:
1309
 
2288 clevermous 1310
        ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver)
1311
        ; len = rx_ring[i].FlagLen & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2);
1312
        ; eax = FlagLen
1313
        cmp     dword [forcedeth_desc_ver], DESC_VER_1
1314
        jne     @f
1315
        and     eax, LEN_MASK_V1
1316
        jmp     .next2
866 shurf 1317
@@:
2288 clevermous 1318
        and     eax, LEN_MASK_V2
866 shurf 1319
 
1320
.next2:
1321
 
2288 clevermous 1322
        ; mov   dword [forcedeth_tmp_len], eax
866 shurf 1323
 
2288 clevermous 1324
        ; valid = 1
1325
        mov     dword [forcedeth_tmp_valid], 1
1326
 
1327
        ; got a valid packet - forward it to the network core
1328
        ; nic->packetlen = len;
1329
        mov     dword [forcedeth_packetlen], eax
1330
        ;
1331
        mov     word [eth_rx_data_len], ax
1332
;;;;;;;;;        DEBUGF 1,"poll: packet len = 0x%x\n", [forcedeth_packetlen]
866 shurf 1333
 
1334
 
2288 clevermous 1335
        ; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen);
1336
        ; Copy packet to system buffer (Ether_buffer)
1337
        ;???? ecx = (len-4)
1338
        mov     ecx, eax
1339
        push    ecx
1340
        shr     ecx, 2
866 shurf 1341
 
2288 clevermous 1342
        ; rxb + (i * RX_NIC_BUFSIZE)
1343
        mov     eax, dword [forcedeth_tmp_i]
1344
        mov     bx, RX_NIC_BUFSIZE
1345
        mul     bx
1346
        add     eax, forcedeth_rxb
866 shurf 1347
 
2288 clevermous 1348
        mov     esi, eax
866 shurf 1349
        mov     edi, Ether_buffer
2288 clevermous 1350
        cld             ; set to increment
1351
        rep movsd       ; mov dword from [esi++] to [edi++]
1352
        pop     ecx
1353
        and     ecx, 3  ; copy rest 1-3 bytes
1354
        rep movsb
866 shurf 1355
 
2288 clevermous 1356
        ; wmb();
1357
        ; ???
866 shurf 1358
 
2288 clevermous 1359
        ; np->cur_rx++;
1360
        inc     dword [forcedeth_cur_rx]
866 shurf 1361
 
2288 clevermous 1362
        ; if (!valid)
1363
        cmp     dword [forcedeth_tmp_valid], 0
1364
        jne     @f
1365
        ;   goto top;
1366
        jmp     .top
866 shurf 1367
@@:
2288 clevermous 1368
        ; alloc_rx(nic);
1369
        call    forcedeth_alloc_rx
866 shurf 1370
 
2288 clevermous 1371
        ; return 1;
1372
        jmp     .return1
866 shurf 1373
 
2288 clevermous 1374
;;;;;   DEBUGF  1,"K : FORCEDETH: poll: ...\n"
866 shurf 1375
 
1376
 
1377
.return0:
2288 clevermous 1378
        mov     eax, 0
1379
        jmp     .return
866 shurf 1380
.return1:
2288 clevermous 1381
        mov     eax, 1
866 shurf 1382
.return:
2288 clevermous 1383
        ;;push  eax
866 shurf 1384
 
2288 clevermous 1385
        ; ????????????????????????????????????????????????
1386
        ; ????? clear interrupt mask/status
1387
        ; read IRQ status
1388
        ;;mov   edi, dword [forcedeth_mapio_addr]
1389
        ;;mov   eax, dword [edi+NvRegIrqStatus]
866 shurf 1390
 
2288 clevermous 1391
        ; clear events
1392
        ;;and   eax, not (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF or NVREG_IRQ_LINK or NVREG_IRQ_TIMER)
866 shurf 1393
 
2288 clevermous 1394
        ; write IRQ status
1395
        ;;mov   dword [edi+NvRegIrqStatus], eax
1396
        ; ????????????????????????????????????????????????
866 shurf 1397
 
2288 clevermous 1398
        ;;pop   eax
1399
        ret
866 shurf 1400
 
1401
 
1402
;***************************************************************************
1403
;   Function
1404
;      forcedeth_transmit
1405
;
1406
;   Description
1407
;       Transmits a packet of data via the ethernet card
1408
;          Pointer to 48 bit destination address in edi
1409
;         Type of packet in bx
1410
;         size of packet in ecx
1411
;         pointer to packet data in esi
1412
;
1413
;***************************************************************************
1414
forcedeth_transmit:
1415
 
2288 clevermous 1416
        ; send the packet to destination
866 shurf 1417
;pusha
2288 clevermous 1418
;DEBUGF 1,"K : FORCEDETH: transmit: packet type = 0x%x\n", ebx
1419
;DEBUGF 1,"K : FORCEDETH: transmit: packet len  = 0x%x\n", ecx
1420
;mov    eax, dword [edi]
1421
;DEBUGF 1,"K : FORCEDETH: transmit: dest adr    = 0x%x\n", eax
1422
;mov    eax, dword [edi+4]
1423
;DEBUGF 1,"K : FORCEDETH: transmit: dest adr2   = 0x%x\n", eax
1424
;mov    eax, dword [node_addr]
1425
;DEBUGF 1,"K : FORCEDETH: transmit: src  adr    = 0x%x\n", eax
1426
;mov    eax, dword [node_addr+4]
1427
;DEBUGF 1,"K : FORCEDETH: transmit: src adr2    = 0x%x\n", eax
866 shurf 1428
;popa
1429
 
2288 clevermous 1430
        ; int nr = np->next_tx % TX_RING
1431
        mov     eax, dword [forcedeth_next_tx]
1432
        and     eax, (TX_RING-1)
1433
        mov     dword [forcedeth_tmp_nr], eax
1434
 
1435
        ; point to the current txb incase multiple tx_rings are used
1436
        ; ptxb = txb + (nr * RX_NIC_BUFSIZE)
1437
        push    ecx
1438
        mov     cx, RX_NIC_BUFSIZE
1439
        mul     cx      ; AX*CX, result to DX:AX
1440
        add     eax, forcedeth_txb
1441
        mov     dword [forcedeth_tmp_ptxb], eax
1442
        push    esi
1443
        mov     esi, edi        ; dst MAC
1444
        mov     edi, eax        ; packet buffer
1445
        cld                     ; set to increment
1446
 
1447
        ; copy the packet to ring buffer
1448
        ; memcpy(ptxb, d, ETH_ALEN);      /* dst */
1449
        movsd
1450
        movsw
1451
 
1452
        ; memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN);      /* src */
1453
        mov     esi, node_addr
1454
        movsd
1455
        movsw
866 shurf 1456
 
2288 clevermous 1457
        ; nstype = htons((u16) t);        /* type */
1458
        ; memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2);        /* type */
1459
        mov     word [edi], bx
1460
        add     edi, 2
1461
 
1462
        ; memcpy(ptxb + ETH_HLEN, p, s);
1463
        pop     esi
1464
        pop     ecx
1465
        push    ecx
1466
        shr     ecx, 2          ; count in dwords
1467
        rep movsd               ; copy dwords from [esi+=4] to [edi+=4]
1468
        pop     ecx
1469
        push    ecx
1470
        and     ecx, 3          ; copy rest 1-3 bytes
1471
        rep movsb               ; copy bytess from [esi++] to [edi++]
866 shurf 1472
 
1473
 
2288 clevermous 1474
        ; s += ETH_HLEN;
1475
        ; while (s < ETH_ZLEN)    /* pad to min length */
1476
        ;  ptxb[s++] = '\0';
1477
        ; pad to min length
1478
        pop     ecx
1479
        add     ecx, ETH_HLEN
1480
        push    ecx             ; header length + data length
1481
        cmp     ecx, ETH_ZLEN
1482
        jge     @f
1483
        mov     eax, ETH_ZLEN
1484
        sub     eax, ecx
1485
        xchg    eax, ecx
1486
        mov     al, 0
1487
        rep stosb               ; copy byte from al to [edi++]
866 shurf 1488
 
1489
@@:
1490
 
2288 clevermous 1491
        ; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb);
1492
        mov     eax, dword [forcedeth_tmp_nr]
1493
        mov     cl, sizeof.forcedeth_TxDesc
1494
        mul     cl
1495
        add     eax, forcedeth_tx_ring
1496
        mov     ebx, eax
1497
        mov     eax, dword [forcedeth_tmp_ptxb]
1498
        sub     eax, OS_BASE            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1499
        mov     [ebx + forcedeth_TxDesc.PacketBuffer], eax
866 shurf 1500
 
2288 clevermous 1501
;DEBUGF 1,"K : FORCEDETH: transmit: PacketBuffer = 0x%x\n", eax
1502
;DEBUGF 1,"K : FORCEDETH: transmit: txflags = 0x%x\n", [forcedeth_txflags]:8
866 shurf 1503
 
2288 clevermous 1504
        ; wmb();
1505
        ; tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags);
1506
        pop     eax             ; header length + data length
1507
        mov     ecx, dword [forcedeth_txflags]
1508
        or      eax, ecx
1509
        mov     [ebx + forcedeth_TxDesc.FlagLen], eax
866 shurf 1510
 
2288 clevermous 1511
        ; writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl);
1512
        mov     edi, dword [forcedeth_mapio_addr]
1513
        mov     eax, dword [forcedeth_desc_ver]
1514
        or      eax, NVREG_TXRXCTL_KICK
1515
        mov     dword [edi+NvRegTxRxControl], eax
866 shurf 1516
 
2288 clevermous 1517
        ; pci_push(base);
1518
        call    forcedeth_pci_push
866 shurf 1519
 
2288 clevermous 1520
        ; np->next_tx++
1521
        inc     dword [forcedeth_next_tx]; may be need to reset? Overflow?
866 shurf 1522
 
2288 clevermous 1523
        ret
866 shurf 1524
 
1525
;***************************************************************************
1526
;   Function
1527
;      forcedeth_cable
1528
;
1529
;   Description
2288 clevermous 1530
;       Return AL=0, if cable is not connected
1531
;       Returm AL=1, if cable is connected
866 shurf 1532
;
1533
;***************************************************************************
1534
forcedeth_cable:
1535
 
2288 clevermous 1536
        mov     al, 1
1537
        cmp     dword [forcedeth_nocable], 1
1538
        jne     .return
1539
        mov     al, 0
866 shurf 1540
 
1541
.return:
2288 clevermous 1542
        ret
866 shurf 1543
 
1544
;***************************************************************************
2288 clevermous 1545
 
1546
 
866 shurf 1547
; read/write a register on the PHY.
1548
; Caller must guarantee serialization
1549
; Input:  EAX - miireg, EBX - addr, ECX - value
1550
; Output: EAX - retval
1551
forcedeth_mii_rw:
2288 clevermous 1552
        push    ebx
1553
        push    eax     ; save miireg
1554
        ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus)
1555
        mov     edi, dword [forcedeth_mapio_addr]
1556
        mov     dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK
866 shurf 1557
 
2288 clevermous 1558
        ; reg = readl(base + NvRegMIIControl)
1559
        mov     eax, dword [edi+NvRegMIIControl]
1560
        test    eax, NVREG_MIICTL_INUSE
1561
        jz      @f
1562
        ; writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl)
1563
        mov     dword [edi+NvRegMIIControl], NVREG_MIICTL_INUSE
1564
        ; nv_udelay(NV_MIIBUSY_DELAY)
1565
        mov     esi, NV_MIIBUSY_DELAY
1566
        call    forcedeth_nv_udelay
866 shurf 1567
@@:
2288 clevermous 1568
        ; reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg
1569
        pop     edx     ; restore miireg
1570
        mov     eax, ebx
1571
        shl     eax, NVREG_MIICTL_ADDRSHIFT
1572
        or      eax, edx
1573
        mov     dword [forcedeth_tmp_reg], eax
866 shurf 1574
 
2288 clevermous 1575
        cmp     ecx, MII_READ
1576
        je      @f
1577
        ; writel(value, base + NvRegMIIData)
1578
        mov     dword [edi+NvRegMIIData], ecx
1579
        ; reg |= NVREG_MIICTL_WRITE
1580
        or      dword [forcedeth_tmp_reg], NVREG_MIICTL_WRITE
866 shurf 1581
@@:
2288 clevermous 1582
        ; writel(reg, base + NvRegMIIControl)
1583
        mov     eax, dword [forcedeth_tmp_reg]
1584
        mov     dword [edi+NvRegMIIControl], eax
866 shurf 1585
 
2288 clevermous 1586
        push    ebx edx edi     ;;;;;;;;;;;;;;;;;;;;;;
866 shurf 1587
 
2288 clevermous 1588
        ; reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)
1589
        stdcall forcedeth_reg_delay, NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, 0
866 shurf 1590
 
2288 clevermous 1591
        pop     edi edx ebx     ;;;;;;;;;;;;;;;;;;;;;;
866 shurf 1592
 
2288 clevermous 1593
        test    eax, eax
1594
        jz      @f
1595
;;;;;;;;        DEBUGF  1,"K : FORCEDETH: mii_rw of reg %d at PHY %d timed out.\n", edx, ebx
1596
        mov     eax, 0xffffffff
1597
        jmp     .return
866 shurf 1598
@@:
2288 clevermous 1599
        cmp     ecx, MII_READ
1600
        je      @f
1601
        ;it was a write operation - fewer failures are detectable
1602
;;;;;;;;        DEBUGF  1,"K : FORCEDETH: mii_rw wrote 0x%x to reg %d at PHY %d\n", ecx, edx, ebx
1603
        mov     eax, 0
1604
        jmp     .return
866 shurf 1605
@@:
2288 clevermous 1606
        ; readl(base + NvRegMIIStatus)
1607
        mov     eax, dword [edi+NvRegMIIStatus]
1608
        test    eax, NVREG_MIISTAT_ERROR
1609
        jz      @f
1610
;;;;;;;;        DEBUGF  1,"K : FORCEDETH: mii_rw of reg %d at PHY %d failed.\n", edx, ebx
1611
        mov     eax, 0xffffffff
1612
        jmp     .return
866 shurf 1613
@@:
2288 clevermous 1614
        ; retval = readl(base + NvRegMIIData)
1615
        mov     eax, dword [edi+NvRegMIIData]
1616
;;;;;;;;        DEBUGF  1,"K : FORCEDETH: mii_rw read from reg %d at PHY %d: 0x%x.\n", edx, ebx, eax
866 shurf 1617
.return:
2288 clevermous 1618
        pop     ebx
1619
        ret
866 shurf 1620
 
1621
 
1622
 
1623
; Input:  ESI - delay
1624
; Output: none
1625
forcedeth_nv_udelay:
1626
 
2288 clevermous 1627
        push    ebx
1628
        cmp     dword [forcedeth_in_shutdown], 0
1629
        jne     @f
1630
        call    forcedeth_udelay        ; delay on ESI
1631
        jmp     .return
866 shurf 1632
@@:
2288 clevermous 1633
 
866 shurf 1634
.loop:
2288 clevermous 1635
        cmp     esi, 0
1636
        je      .return
1637
        ; Don't allow an rx_ring overflow to happen
1638
        ; while shutting down the NIC it will
1639
        ; kill the receive function.
866 shurf 1640
 
2288 clevermous 1641
        call    forcedeth_drop_rx
1642
        mov     ebx, 3          ; sleep = 3
1643
        cmp     ebx, esi        ; if(sleep > delay)
1644
        jle     @f
1645
        mov     ebx, esi        ; sleep = delay
866 shurf 1646
@@:
2288 clevermous 1647
        push    esi
1648
        mov     esi, ebx
1649
        ; udelay(sleep)
1650
        call    forcedeth_udelay        ; delay on ESI
1651
        pop     esi
1652
        sub     esi, ebx                ; delay -= sleep
1653
        jmp     .loop
866 shurf 1654
 
1655
.return:
2288 clevermous 1656
        pop     ebx
1657
        ret
866 shurf 1658
 
1659
 
1660
; Input:  none
1661
; Output: none
1662
forcedeth_drop_rx:
1663
 
2288 clevermous 1664
        push    eax ebx ecx edi
866 shurf 1665
 
2288 clevermous 1666
        ; events = readl(base + NvRegIrqStatus)
1667
        mov     edi, dword [forcedeth_mapio_addr]
1668
        mov     eax, dword [edi+NvRegIrqStatus]
866 shurf 1669
 
2288 clevermous 1670
        test    eax, eax
1671
        jz      @f
1672
        ; writel(events, base + NvRegIrqStatus)
1673
        mov     dword [edi+NvRegIrqStatus], eax
866 shurf 1674
@@:
2288 clevermous 1675
        ;if (!(events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)))
1676
        test    eax, (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF)
1677
        jz      .return
1678
 
1679
.loop:
1680
        ; i = np->cur_rx % RX_RING
1681
        mov     eax, dword [forcedeth_cur_rx]
1682
        and     eax, (RX_RING-1)
1683
        ; //Flags = le32_to_cpu(rx_ring[i].FlagLen)
1684
        ; Flags = rx_ring[i].FlagLen
1685
        mov     cl, sizeof.forcedeth_RxDesc
1686
        mul     cl
1687
        add     eax, forcedeth_rx_ring
1688
        mov     ebx, eax
1689
        mov     eax, [ebx + forcedeth_RxDesc.FlagLen]
1690
        ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver)
1691
        ; > len = Flags & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2)
1692
        ; ??? len don't used later !!! ???
1693
        ; ...
1694
        test    eax, NV_RX_AVAIL
1695
        jnz     .return         ; still owned by hardware,
1696
        ; wmb()
1697
        ; ??? may be empty function ???
1698
        ; np->cur_rx++
1699
        inc     dword [forcedeth_cur_rx]
1700
        ; alloc_rx(NULL)
1701
        call    forcedeth_alloc_rx
1702
.return:
1703
        pop     edi ecx ebx eax
1704
        ret
866 shurf 1705
 
1706
 
1707
; Fill rx ring entries.
1708
; Return 1 if the allocations for the skbs failed and the
1709
; rx engine is without Available descriptors
1710
; Input:  none
1711
; Output: none
1712
forcedeth_alloc_rx:
1713
 
2288 clevermous 1714
        push    eax ebx ecx edx
1715
        ; refill_rx = np->refill_rx
1716
        mov     ecx, dword [forcedeth_refill_rx]
866 shurf 1717
.loop:
2288 clevermous 1718
        cmp     dword [forcedeth_cur_rx], ecx
1719
        je      .loop_end
1720
        ; nr = refill_rx % RX_RING
1721
        mov     eax, ecx
1722
        and     eax, (RX_RING-1)        ; nr
1723
        ; rx_ring[nr].PacketBuffer = &rxb[nr * RX_NIC_BUFSIZE]
1724
        push    ecx
1725
        push    eax
1726
        mov     cl, sizeof.forcedeth_RxDesc
1727
        mul     cl
1728
        add     eax, forcedeth_rx_ring
1729
        mov     ebx, eax
1730
        pop     eax
1731
        mov     cx, RX_NIC_BUFSIZE
1732
        mul     cx
1733
        pop     ecx
1734
        add     eax, forcedeth_rxb
1735
        sub     eax, OS_BASE    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1736
        mov     [ebx + forcedeth_RxDesc.PacketBuffer], eax
1737
        ; wmb()
1738
        ; ...
1739
        ; rx_ring[nr].FlagLen = RX_NIC_BUFSIZE | NV_RX_AVAIL
1740
        mov     [ebx + forcedeth_RxDesc.FlagLen], (RX_NIC_BUFSIZE or NV_RX_AVAIL)
1741
        inc     ecx
1742
        jmp     .loop
1743
 
866 shurf 1744
.loop_end:
2288 clevermous 1745
        ; np->refill_rx = refill_rx
1746
        mov     [forcedeth_refill_rx], ecx
866 shurf 1747
.return:
2288 clevermous 1748
        pop     edx ecx ebx eax
1749
        ret
866 shurf 1750
 
1751
 
1752
; Delay in millisec
1753
; Input:  ESI - delay in ms
1754
; Output: none
1755
forcedeth_udelay:
1756
        call    delay_ms
2288 clevermous 1757
        ret
866 shurf 1758
 
1759
; Input:  offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword
1760
; Output: EAX - 0|1
2288 clevermous 1761
;;;;proc        forcedeth_reg_delay,offset:word,mask:dword,target:dword,delay:word,delaymax:word,msg:dword
1762
proc    forcedeth_reg_delay,offset:dword,mask:dword,target:dword,delay:dword,delaymax:dword,msg:dword
866 shurf 1763
 
2288 clevermous 1764
        push    ebx esi edi
1765
        ; pci_push(base)
1766
        call    forcedeth_pci_push
866 shurf 1767
.loop:
2288 clevermous 1768
        ; nv_udelay(delay)
1769
        mov     esi, dword [delay]
1770
        call    forcedeth_nv_udelay     ; delay in esi
1771
        mov     eax, dword [delaymax]
1772
        sub     eax, dword [delay]
1773
        mov     dword [delaymax], eax
1774
        ; if (delaymax < 0)
1775
        test    dword [delaymax], 0x80000000
1776
        jz      @f
1777
        ; return 1
1778
        mov     eax, 1
1779
        jmp     .return
866 shurf 1780
@@:
2288 clevermous 1781
        ; while ((readl(base + offset) & mask) != target)
1782
        mov     edi, dword [forcedeth_mapio_addr]
1783
        mov     ebx, dword [offset]
1784
        mov     eax, dword [edi+ebx]
1785
        and     eax, dword [mask]
1786
        cmp     eax, dword [target]
1787
        jne     .loop
1788
        xor     eax, eax
866 shurf 1789
.return:
2288 clevermous 1790
        pop     edi esi ebx
1791
        ret
866 shurf 1792
endp
1793
 
1794
 
1795
; Input:  none
1796
; Output: none
1797
forcedeth_pci_push:
2288 clevermous 1798
        push    eax edi
1799
        ;force out pending posted writes
1800
        mov     edi, dword [forcedeth_mapio_addr]
1801
        mov     eax, dword [edi]
1802
        pop     edi eax
1803
        ret
866 shurf 1804
 
1805
 
1806
; Input:  none
1807
; Output: EAX - result (0 = OK, other = error)
1808
forcedeth_phy_init:
1809
 
2288 clevermous 1810
        push    ebx ecx
1811
 
1812
        ; set advertise register
1813
        ; reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
866 shurf 1814
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1815
        mov     ebx, dword [forcedeth_phyaddr]
1816
        mov     eax, MII_ADVERTISE
1817
        mov     ecx, MII_READ
1818
        call    forcedeth_mii_rw        ; reg = eax
866 shurf 1819
 
2288 clevermous 1820
        ; reg |=
1821
        ; (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF |
1822
        ;  ADVERTISE_100FULL | 0x800 | 0x400);
1823
        or      eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400)
866 shurf 1824
 
2288 clevermous 1825
        ; if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg))
866 shurf 1826
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1827
        mov     ecx, eax        ; reg
1828
        mov     eax, MII_ADVERTISE
1829
        call    forcedeth_mii_rw        ; eax -> return
866 shurf 1830
 
2288 clevermous 1831
        test    eax, eax
1832
        jz      @f
1833
        ; printf("phy write to advertise failed.\n");
1834
        DEBUGF 1," K : FORCEDETH: phy write to advertise failed.\n"
866 shurf 1835
 
2288 clevermous 1836
        ; return PHY_ERROR;
1837
        mov     eax, PHY_ERROR
1838
        jmp     .return
866 shurf 1839
@@:
2288 clevermous 1840
        ; get phy interface type
1841
        ; phyinterface = readl(base + NvRegPhyInterface);
1842
        mov     edi, dword [forcedeth_mapio_addr]
1843
        mov     eax, dword [edi+NvRegPhyInterface]      ; phyinterface = eax
1844
        mov     dword [forcedeth_tmp_phyinterface], eax
866 shurf 1845
 
1846
;;;;;;;;;;;;;;;;;;;;;;;;;
1847
DEBUGF 1," K : FORCEDETH: phy interface type = 0x%x\n", [forcedeth_tmp_phyinterface]:8
1848
;;;;;;;;;;;;;;;;;;;;;;;;;
1849
 
2288 clevermous 1850
        ; see if gigabit phy
1851
        ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
866 shurf 1852
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1853
        mov     eax, MII_BMSR
1854
        mov     ecx, MII_READ
1855
        call    forcedeth_mii_rw        ; mii_status = eax
1856
 
1857
        ; if (mii_status & PHY_GIGABIT)
1858
        test    eax, PHY_GIGABIT
1859
        jnz     .gigabit
1860
        ; np->gigabit = 0;
1861
        mov     dword [forcedeth_gigabit], 0
1862
        jmp     .next_if
866 shurf 1863
 
1864
.gigabit:
2288 clevermous 1865
        ; np->gigabit = PHY_GIGABIT;
1866
        mov     dword [forcedeth_gigabit], PHY_GIGABIT
866 shurf 1867
 
2288 clevermous 1868
        ; mii_control_1000 =  mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ);
866 shurf 1869
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1870
        mov     eax, MII_1000BT_CR
1871
        mov     ecx, MII_READ
1872
        call    forcedeth_mii_rw        ; mii_control_1000 = eax
1873
 
1874
        ; mii_control_1000 &= ~ADVERTISE_1000HALF;
1875
        and     eax, (not ADVERTISE_1000HALF)
866 shurf 1876
 
2288 clevermous 1877
        ; if (phyinterface & PHY_RGMII)
1878
        test    dword [forcedeth_tmp_phyinterface], PHY_RGMII
1879
        jz      @f
1880
        ; mii_control_1000 |= ADVERTISE_1000FULL
1881
        or      eax, ADVERTISE_1000FULL
1882
        jmp     .next
866 shurf 1883
@@:
2288 clevermous 1884
        ; mii_control_1000 &= ~ADVERTISE_1000FULL
1885
        and     eax, (not ADVERTISE_1000FULL)
866 shurf 1886
 
1887
.next:
2288 clevermous 1888
        ; if (mii_rw(nic, np->phyaddr, MII_1000BT_CR, mii_control_1000))
866 shurf 1889
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1890
        mov     ecx, eax
1891
        mov     eax, MII_1000BT_CR
1892
        call    forcedeth_mii_rw        ; eax -> return
866 shurf 1893
 
2288 clevermous 1894
        test    eax, eax
1895
        jz      .next_if
866 shurf 1896
 
2288 clevermous 1897
        ; printf("phy init failed.\n");
1898
        DEBUGF 1," K : FORCEDETH: phy init failed.\n"
866 shurf 1899
 
2288 clevermous 1900
        ; return PHY_ERROR;
1901
        mov     eax, PHY_ERROR
1902
        jmp     .return
866 shurf 1903
 
1904
.next_if:
1905
 
2288 clevermous 1906
        ; reset the phy
1907
        ; if (phy_reset(nic))
1908
        call    forcedeth_phy_reset
1909
        test    eax, eax
1910
        jz      @f
1911
        ; printf("phy reset failed\n")
1912
        DEBUGF 1," K : FORCEDETH: phy reset failed.\n"
1913
        ; return PHY_ERROR
1914
        mov     eax, PHY_ERROR
1915
        jmp     .return
866 shurf 1916
@@:
1917
 
2288 clevermous 1918
        ; phy vendor specific configuration
1919
        ; if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII))
1920
        cmp     dword [forcedeth_phy_oui], PHY_OUI_CICADA
1921
        jne     .next_if2
1922
        test    dword [forcedeth_tmp_phyinterface], PHY_RGMII
1923
        jz      .next_if2
866 shurf 1924
 
2288 clevermous 1925
        ; phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ)
866 shurf 1926
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1927
        mov     eax, MII_RESV1
1928
        mov     ecx, MII_READ
1929
        call    forcedeth_mii_rw        ; phy_reserved = eax
1930
 
1931
        ; phy_reserved &= ~(PHY_INIT1 | PHY_INIT2)
1932
        and     eax, (not (PHY_INIT1 or PHY_INIT2))
1933
        ; phy_reserved |= (PHY_INIT3 | PHY_INIT4)
1934
        or      eax, (PHY_INIT3 or PHY_INIT4)
1935
 
1936
        ; if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved))
866 shurf 1937
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1938
        mov     ecx, eax
1939
        mov     eax, MII_RESV1
1940
        call    forcedeth_mii_rw        ; eax -> return
1941
        test    eax, eax
1942
        jz      @f
1943
        ; printf("phy init failed.\n")
1944
        DEBUGF 1," K : FORCEDETH: phy init failed.\n"
1945
        ; return PHY_ERROR
1946
        mov     eax, PHY_ERROR
1947
        jmp     .return
866 shurf 1948
@@:
2288 clevermous 1949
        ; phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ);
866 shurf 1950
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1951
        mov     eax, MII_NCONFIG
1952
        mov     ecx, MII_READ
1953
        call    forcedeth_mii_rw        ; phy_reserved = eax
866 shurf 1954
 
2288 clevermous 1955
        ; phy_reserved |= PHY_INIT5
1956
        or      eax, PHY_INIT5
1957
 
1958
        ; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved))
866 shurf 1959
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1960
        mov     ecx, eax
1961
        mov     eax, MII_NCONFIG
1962
        call    forcedeth_mii_rw        ; eax -> return
1963
        test    eax, eax
1964
        jz      .next_if2
1965
        ; printf("phy init failed.\n")
1966
        DEBUGF 1," K : FORCEDETH: phy init failed.\n"
1967
        ; return PHY_ERROR
1968
        mov     eax, PHY_ERROR
1969
        jmp     .return
866 shurf 1970
 
1971
.next_if2:
1972
 
2288 clevermous 1973
        ; if (np->phy_oui == PHY_OUI_CICADA)
1974
        cmp     dword [forcedeth_phy_oui], PHY_OUI_CICADA
1975
        jne     .restart
1976
 
1977
        ; phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ)
866 shurf 1978
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 1979
        mov     eax, MII_SREVISION
1980
        mov     ecx, MII_READ
1981
        call    forcedeth_mii_rw        ; phy_reserved = eax
1982
 
1983
        ; phy_reserved |= PHY_INIT6
1984
        or      eax, PHY_INIT6
1985
 
1986
        ; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved))
1987
        mov     ecx, eax
1988
        mov     eax, MII_SREVISION
1989
        call    forcedeth_mii_rw        ; eax -> return
1990
        test    eax, eax
1991
        jz      .restart
1992
        ; printf("phy init failed.\n");
1993
        DEBUGF 1," K : FORCEDETH: phy init failed.\n"
1994
        ; return PHY_ERROR;
1995
        jmp     .return
866 shurf 1996
 
1997
.restart:
2288 clevermous 1998
        ; restart auto negotiation
1999
        ; mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ)
866 shurf 2000
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2001
        mov     eax, MII_BMCR
2002
        mov     ecx, MII_READ
2003
        call    forcedeth_mii_rw        ; mii_control = eax
866 shurf 2004
 
2288 clevermous 2005
        ; mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE)
2006
        or      eax, (BMCR_ANRESTART or BMCR_ANENABLE)
2007
 
2008
        ; if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control))
2009
        mov     ecx, eax
2010
        mov     eax, MII_BMCR
2011
        call    forcedeth_mii_rw        ; eax -> return
2012
        test    eax, eax
2013
        jz      .ok
866 shurf 2014
 
2288 clevermous 2015
        ; return PHY_ERROR;
2016
        mov     eax, PHY_ERROR
2017
        jmp     .return
866 shurf 2018
 
2019
.ok:
2288 clevermous 2020
        mov     eax, 0
866 shurf 2021
.return:
2288 clevermous 2022
        pop     ecx ebx
2023
        ret
866 shurf 2024
 
2025
 
2026
; Input:  none
2027
; Output: EAX - result (0 = OK, other = error)
2028
forcedeth_phy_reset:
2029
 
2288 clevermous 2030
        push    ebx ecx edx
866 shurf 2031
 
2288 clevermous 2032
        ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
866 shurf 2033
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2034
        mov     ebx, dword [forcedeth_phyaddr]
2035
        mov     eax, MII_BMCR
2036
        mov     ecx, MII_READ
2037
        call    forcedeth_mii_rw        ; miicontrol = eax
866 shurf 2038
 
2288 clevermous 2039
        ; miicontrol |= BMCR_RESET;
2040
        or      eax, BMCR_RESET
2041
        push    eax
866 shurf 2042
 
2288 clevermous 2043
        ; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol))
866 shurf 2044
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2045
        mov     ecx, eax
2046
        mov     eax, MII_BMCR
2047
        call    forcedeth_mii_rw        ; miicontrol = eax
866 shurf 2048
 
2288 clevermous 2049
        test    eax, eax
2050
        jz      @f
2051
        pop     eax
2052
        mov     eax, 0xffffffff
2053
        jmp     .return
866 shurf 2054
@@:
2288 clevermous 2055
        pop     eax
866 shurf 2056
 
2288 clevermous 2057
        ; wait for 500ms
2058
        ; mdelay(500)
2059
        mov     esi, 500
2060
        call    forcedeth_udelay
866 shurf 2061
 
2288 clevermous 2062
        ; must wait till reset is deasserted
2063
        ; while (miicontrol & BMCR_RESET) {
2064
        mov     edx, 100
866 shurf 2065
.while_loop:
2288 clevermous 2066
        test    eax, BMCR_RESET
2067
        jz      .while_loop_exit
866 shurf 2068
 
2288 clevermous 2069
        ; mdelay(10);
2070
        mov     esi, 10
2071
        call    forcedeth_udelay
866 shurf 2072
 
2288 clevermous 2073
        ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
866 shurf 2074
        ; EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2075
        mov     eax, MII_BMCR
2076
        mov     ecx, MII_READ
2077
        call    forcedeth_mii_rw        ; miicontrol = eax
866 shurf 2078
 
2288 clevermous 2079
        ; FIXME: 100 tries seem excessive
2080
        ; if (tries++ > 100)
2081
        dec     edx
2082
        jnz     .while_loop
2083
        ; return -1;
2084
        mov     eax, 0xffffffff
2085
        jmp     .return
866 shurf 2086
.while_loop_exit:
2288 clevermous 2087
        ; return 0
2088
        mov     eax, 0
2089
.return:
2090
        pop     edx ecx ebx
2091
        ret
866 shurf 2092
 
2093
; Input:  none
2094
; Output: none
2095
forcedeth_mac_reset:
2288 clevermous 2096
        push    esi edi
866 shurf 2097
 
2288 clevermous 2098
        ; dprintf("mac_reset\n")
2099
        DEBUGF 1," K : FORCEDETH: mac_reset.\n"
866 shurf 2100
 
2288 clevermous 2101
        ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl)
2102
        mov     edi, dword [forcedeth_mapio_addr]
2103
        mov     eax, dword [forcedeth_desc_ver]
2104
        or      eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET)
2105
        mov     dword [edi+NvRegTxRxControl], eax
866 shurf 2106
 
2288 clevermous 2107
        ; pci_push(base)
2108
        call    forcedeth_pci_push
2109
 
2110
        ; writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset)
2111
        mov     dword [edi+NvRegMacReset], NVREG_MAC_RESET_ASSERT
866 shurf 2112
 
2288 clevermous 2113
        ; pci_push(base)
2114
        call    forcedeth_pci_push
866 shurf 2115
 
2288 clevermous 2116
        ; udelay(NV_MAC_RESET_DELAY)
2117
        mov     esi, NV_MAC_RESET_DELAY
2118
        call    forcedeth_nv_udelay
866 shurf 2119
 
2288 clevermous 2120
        ; writel(0, base + NvRegMacReset)
2121
        mov     dword [edi+NvRegMacReset], 0
866 shurf 2122
 
2288 clevermous 2123
        ; pci_push(base)
2124
        call    forcedeth_pci_push
2125
 
2126
        ; udelay(NV_MAC_RESET_DELAY)
2127
        mov     esi, NV_MAC_RESET_DELAY
2128
        call    forcedeth_nv_udelay
866 shurf 2129
 
2288 clevermous 2130
        ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl)
2131
        mov     eax, dword [forcedeth_desc_ver]
2132
        or      eax, NVREG_TXRXCTL_BIT2
2133
        mov     dword [edi+NvRegTxRxControl], eax
2134
 
2135
        ; pci_push(base)
2136
        call    forcedeth_pci_push
866 shurf 2137
 
2288 clevermous 2138
        pop     edi esi
2139
        ret
866 shurf 2140
 
2141
; Input:  none
2142
; Output: none
2143
forcedeth_init_ring:
2288 clevermous 2144
        push    eax ebx ecx
866 shurf 2145
 
2146
        ; np->next_tx = np->nic_tx = 0
2288 clevermous 2147
        mov     dword[forcedeth_next_tx], 0
2148
        mov     dword[forcedeth_nic_tx], 0
866 shurf 2149
 
2150
        ; for (i = 0; i < TX_RING; i++)
2288 clevermous 2151
        mov     ecx, TX_RING
866 shurf 2152
 
2153
.for_loop:
2154
        ;        tx_ring[i].FlagLen = 0;
2288 clevermous 2155
        mov     eax, ecx
2156
        dec     eax
2157
        mov     bl, sizeof.forcedeth_TxDesc
2158
        mul     bl
2159
        add     eax, forcedeth_tx_ring
2160
        mov     ebx, eax
2161
        mov     dword [ebx + forcedeth_TxDesc.FlagLen], 0
2162
        loop    .for_loop
866 shurf 2163
 
2164
        ; np->cur_rx = RX_RING;
2288 clevermous 2165
        mov     dword [forcedeth_cur_rx], RX_RING
866 shurf 2166
        ; np->refill_rx = 0;
2288 clevermous 2167
        mov     dword [forcedeth_refill_rx], 0
866 shurf 2168
 
2288 clevermous 2169
        ;for (i = 0; i < RX_RING; i++)
2170
        mov     ecx, RX_RING
866 shurf 2171
 
2172
.for_loop2:
2173
        ;        rx_ring[i].FlagLen = 0;
2288 clevermous 2174
        mov     eax, ecx
2175
        dec     eax
2176
        mov     bl, sizeof.forcedeth_RxDesc
2177
        mul     bl
2178
        add     eax, forcedeth_rx_ring
2179
        mov     ebx, eax
2180
        mov     dword [ebx + forcedeth_RxDesc.FlagLen], 0
2181
        loop    .for_loop2
866 shurf 2182
 
2288 clevermous 2183
        ; alloc_rx(nic);
2184
        call    forcedeth_alloc_rx
866 shurf 2185
 
2186
.return:
2288 clevermous 2187
        pop     ecx ebx eax
2188
        ret
866 shurf 2189
 
2190
; Input:  none
2191
; Output: none
2192
forcedeth_txrx_reset:
2288 clevermous 2193
        push    eax esi edi
866 shurf 2194
 
2288 clevermous 2195
        ; dprintf(("txrx_reset\n"))
2196
        DEBUGF 1," K : FORCEDETH: txrx_reset.\n"
866 shurf 2197
 
2288 clevermous 2198
        ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl)
2199
        mov     edi, dword [forcedeth_mapio_addr]
2200
        mov     eax, dword [forcedeth_desc_ver]
2201
        or      eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET)
2202
        mov     dword [edi+NvRegTxRxControl], eax
866 shurf 2203
 
2288 clevermous 2204
        ; pci_push(base)
2205
        call    forcedeth_pci_push
866 shurf 2206
 
2288 clevermous 2207
        ; nv_udelay(NV_TXRX_RESET_DELAY)
2208
        mov     esi, NV_TXRX_RESET_DELAY
2209
        call    forcedeth_nv_udelay
866 shurf 2210
 
2288 clevermous 2211
        ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl)
2212
        mov     eax, dword [forcedeth_desc_ver]
2213
        or      eax, NVREG_TXRXCTL_BIT2
2214
        mov     dword [edi+NvRegTxRxControl], eax
2215
 
2216
        ; pci_push(base)
2217
        call    forcedeth_pci_push
866 shurf 2218
 
2219
.return:
2288 clevermous 2220
        pop     edi esi eax
2221
        ret
866 shurf 2222
 
2223
; Input:  none
2224
; Output: none
2225
forcedeth_set_multicast:
2288 clevermous 2226
        push    edi
866 shurf 2227
 
2288 clevermous 2228
        ; u32 addr[2];
2229
        ; u32 mask[2];
2230
        ; u32 pff;
2231
        ; u32 alwaysOff[2];
2232
        ; u32 alwaysOn[2];
2233
        ;
2234
        ; memset(addr, 0, sizeof(addr));
2235
        ; memset(mask, 0, sizeof(mask));
2236
        ;
2237
        ; pff = NVREG_PFF_MYADDR;
2238
        ;
2239
        ; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
2240
        ;
2241
        ; addr[0] = alwaysOn[0];
2242
        ; addr[1] = alwaysOn[1];
2243
        ; mask[0] = alwaysOn[0] | alwaysOff[0];
2244
        ; mask[1] = alwaysOn[1] | alwaysOff[1];
2245
        ;
2246
        ; addr[0] |= NVREG_MCASTADDRA_FORCE;
2247
        ; pff |= NVREG_PFF_ALWAYS;
2248
        ; stop_rx();
2249
        call    forcedeth_stop_rx
2250
        ; writel(addr[0], base + NvRegMulticastAddrA);
2251
        mov     edi, dword [forcedeth_mapio_addr]
2252
        mov     dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE
2253
        ; writel(addr[1], base + NvRegMulticastAddrB);
2254
        mov     dword [edi+NvRegMulticastAddrB], 0
2255
        ; writel(mask[0], base + NvRegMulticastMaskA);
2256
        mov     dword [edi+NvRegMulticastMaskA], 0
2257
        ; writel(mask[1], base + NvRegMulticastMaskB);
2258
        mov     dword [edi+NvRegMulticastMaskB], 0
2259
        ; writel(pff, base + NvRegPacketFilterFlags);
2260
        mov     dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_MYADDR or NVREG_PFF_ALWAYS)
2261
        ; start_rx(nic);
2262
        call    forcedeth_start_rx
866 shurf 2263
 
2264
.return:
2288 clevermous 2265
        pop     edi
2266
        ret
866 shurf 2267
 
2268
; Input:  none
2269
; Output: none
2270
forcedeth_start_rx:
2288 clevermous 2271
        push    edi
866 shurf 2272
 
2288 clevermous 2273
        ; dprintf(("start_rx\n"))
2274
        DEBUGF 1," K : FORCEDETH: start_rx.\n"
866 shurf 2275
 
2288 clevermous 2276
        ; Already running? Stop it.
2277
        ; if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
2278
        mov     edi, dword [forcedeth_mapio_addr]
2279
        mov     eax, dword [edi+NvRegReceiverControl]
2280
        test    eax, NVREG_RCVCTL_START
2281
        jz      @f
2282
        ; writel(0, base + NvRegReceiverControl)
2283
        mov     dword [edi+NvRegReceiverControl], 0
2284
        ; pci_push(base)
2285
        call    forcedeth_pci_push
866 shurf 2286
 
2287
@@:
2288 clevermous 2288
 
2289
        ; writel(np->linkspeed, base + NvRegLinkSpeed);
2290
        mov     eax, dword [forcedeth_linkspeed]
2291
        mov     dword [edi+NvRegLinkSpeed], eax
2292
        ; pci_push(base);
2293
        call    forcedeth_pci_push
2294
        ; writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
2295
        mov     dword [edi+NvRegReceiverControl], NVREG_RCVCTL_START
2296
        ; pci_push(base);
2297
        call    forcedeth_pci_push
866 shurf 2298
 
2299
.return:
2288 clevermous 2300
        pop     edi
2301
        ret
866 shurf 2302
 
2303
; Input:  none
2304
; Output: none
2305
forcedeth_stop_rx:
2288 clevermous 2306
        push    esi edi
866 shurf 2307
 
2288 clevermous 2308
        ; dprintf(("stop_rx\n"))
2309
        DEBUGF 1," K : FORCEDETH: stop_rx.\n"
866 shurf 2310
 
2288 clevermous 2311
        ; writel(0, base + NvRegReceiverControl)
2312
        mov     edi, dword [forcedeth_mapio_addr]
2313
        mov     dword [edi+NvRegReceiverControl], 0
866 shurf 2314
 
2288 clevermous 2315
        push    ebx edx edi     ;;;;;;;;;;;;;;;;;;;;;;
2316
        ; reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy");
2317
        stdcall forcedeth_reg_delay, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, 0
2318
        pop     edi edx ebx     ;;;;;;;;;;;;;;;;;;;;;;
866 shurf 2319
 
2320
 
2288 clevermous 2321
        ; nv_udelay(NV_RXSTOP_DELAY2)
2322
        mov     esi, NV_RXSTOP_DELAY2
2323
        call    forcedeth_nv_udelay
866 shurf 2324
 
2288 clevermous 2325
        ; writel(0, base + NvRegLinkSpeed)
2326
        mov     dword [edi+NvRegLinkSpeed], 0
866 shurf 2327
 
2328
.return:
2288 clevermous 2329
        pop     edi esi
2330
        ret
866 shurf 2331
 
2332
; Input:  none
2333
; Output: EAX
2334
forcedeth_update_linkspeed:
2288 clevermous 2335
        push    ebx ecx esi edi
866 shurf 2336
 
2288 clevermous 2337
        ; BMSR_LSTATUS is latched, read it twice:
2338
        ; we want the current value.
2339
 
2340
        ; mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ)
866 shurf 2341
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2342
        mov     ebx, dword [forcedeth_phyaddr]
2343
        mov     eax, MII_BMSR
2344
        mov     ecx, MII_READ
2345
        call    forcedeth_mii_rw
866 shurf 2346
 
2347
 
2288 clevermous 2348
        ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ)
866 shurf 2349
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2350
        mov     ebx, dword [forcedeth_phyaddr]
2351
        mov     eax, MII_BMSR
2352
        mov     ecx, MII_READ
2353
        call    forcedeth_mii_rw        ; mii_status = eax
2354
 
2355
        ; yhlu
866 shurf 2356
 
2288 clevermous 2357
        ; for(i=0;i<30;i++) {
2358
        mov     ecx, 30
866 shurf 2359
.for_loop:
2288 clevermous 2360
        push    ecx
866 shurf 2361
 
2288 clevermous 2362
        ;  mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
866 shurf 2363
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2364
        ;mov    ebx, dword [forcedeth_phyaddr]
2365
        mov     eax, MII_BMSR
2366
        mov     ecx, MII_READ
2367
        call    forcedeth_mii_rw        ; mii_status = eax
866 shurf 2368
 
2288 clevermous 2369
        ;  if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break;
2370
        test    eax, BMSR_LSTATUS
2371
        jz      @f
2372
        test    eax, BMSR_ANEGCOMPLETE
2373
        jz      @f
2374
        ; break
2375
        pop     ecx
2376
        jmp     .break
2377
 
866 shurf 2378
@@:
2379
 
2288 clevermous 2380
        ;  mdelay(100);
2381
        push    eax     ; ???
2382
        mov     esi, 100
2383
        call    forcedeth_udelay
2384
        pop     eax     ; ???
866 shurf 2385
 
2288 clevermous 2386
        pop     ecx
2387
        loop    .for_loop
866 shurf 2388
 
2389
.break:
2390
 
2288 clevermous 2391
        ; if (!(mii_status & BMSR_LSTATUS)) {
2392
        test    eax, BMSR_LSTATUS
2393
        jnz     @f
866 shurf 2394
 
2288 clevermous 2395
        ; printf("no link detected by phy - falling back to 10HD.\n")
2396
        DEBUGF 1," K : FORCEDETH: update_linkspeed: no link detected by phy - falling back to 10HD.\n"
866 shurf 2397
 
2288 clevermous 2398
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
2399
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
866 shurf 2400
 
2288 clevermous 2401
        ; newdup = 0;
2402
        mov     dword [forcedeth_tmp_newdup], 0
2403
        ; retval = 0;
2404
        mov     dword [forcedeth_tmp_retval], 0
866 shurf 2405
 
2288 clevermous 2406
        ; goto set_speed;
2407
        jmp     .set_speed
866 shurf 2408
 
2409
@@:
2410
 
2288 clevermous 2411
        ; check auto negotiation is complete
2412
        ; if (!(mii_status & BMSR_ANEGCOMPLETE)) {
2413
        test    eax, BMSR_ANEGCOMPLETE
2414
        jnz     @f
866 shurf 2415
 
2288 clevermous 2416
        ; still in autonegotiation - configure nic for 10 MBit HD and wait.
2417
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
2418
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
866 shurf 2419
 
2288 clevermous 2420
        ; newdup = 0
2421
        mov     dword [forcedeth_tmp_newdup], 0
866 shurf 2422
 
2288 clevermous 2423
        ; retval = 0
2424
        mov     dword [forcedeth_tmp_retval], 0
866 shurf 2425
 
2288 clevermous 2426
        ; printf("autoneg not completed - falling back to 10HD.\n")
2427
        DEBUGF 1," K : FORCEDETH: update_linkspeed: autoneg not completed - falling back to 10HD.\n"
866 shurf 2428
 
2288 clevermous 2429
        ; goto set_speed
2430
        jmp     .set_speed
866 shurf 2431
 
2432
@@:
2433
 
2288 clevermous 2434
        ; retval = 1
2435
        mov     dword [forcedeth_tmp_retval], 1
2436
 
2437
        ; if (np->gigabit == PHY_GIGABIT) {
2438
        cmp     dword [forcedeth_gigabit], PHY_GIGABIT
2439
        jne     .end_if
2440
        ; control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ)
866 shurf 2441
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2442
        ;mov    ebx, dword [forcedeth_phyaddr]
2443
        mov     eax, MII_1000BT_CR
2444
        mov     ecx, MII_READ
2445
        call    forcedeth_mii_rw        ; control_1000 = eax
2446
        mov     dword [forcedeth_tmp_control_1000], eax
2447
 
2448
        ; status_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_SR, MII_READ)
866 shurf 2449
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2450
        ;mov    ebx, dword [forcedeth_phyaddr]
2451
        mov     eax, MII_1000BT_SR
2452
        mov     ecx, MII_READ
2453
        call    forcedeth_mii_rw        ; status_1000 = eax
2454
        ;mov    dword [forcedeth_tmp_status_1000], eax
2455
 
2456
        ; if ((control_1000 & ADVERTISE_1000FULL) &&
2457
        ;     (status_1000 & LPA_1000FULL)) {
2458
        test    eax, LPA_1000FULL
2459
        jz      .end_if
2460
        test    dword [forcedeth_tmp_control_1000], ADVERTISE_1000FULL
2461
        jz      .end_if
866 shurf 2462
 
2288 clevermous 2463
        ; printf ("update_linkspeed: GBit ethernet detected.\n")
2464
        DEBUGF 1," K : FORCEDETH: update_linkspeed: GBit ethernet detected.\n"
866 shurf 2465
 
2288 clevermous 2466
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000
2467
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_1000)
866 shurf 2468
 
2288 clevermous 2469
        ; newdup = 1
2470
        mov     dword [forcedeth_tmp_newdup], 1
866 shurf 2471
 
2288 clevermous 2472
        ; goto set_speed
2473
        jmp     .set_speed
866 shurf 2474
 
2475
.end_if:
2476
 
2288 clevermous 2477
        ; adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
866 shurf 2478
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2479
        ;mov    ebx, dword [forcedeth_phyaddr]
2480
        mov     eax, MII_ADVERTISE
2481
        mov     ecx, MII_READ
2482
        call    forcedeth_mii_rw        ; adv = eax
2483
        mov     dword [forcedeth_tmp_adv], eax
866 shurf 2484
 
2288 clevermous 2485
        ; lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ);
866 shurf 2486
        ;EBX - addr, EAX - miireg, ECX - value
2288 clevermous 2487
        ;mov    ebx, dword [forcedeth_phyaddr]
2488
        mov     eax, MII_LPA
2489
        mov     ecx, MII_READ
2490
        call    forcedeth_mii_rw        ; lpa = eax
2491
        mov     dword [forcedeth_tmp_lpa], eax
866 shurf 2492
 
2288 clevermous 2493
        ; dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa));
2494
        DEBUGF 1," K : FORCEDETH: update_linkspeed: PHY advertises 0x%x, lpa 0x%x.\n", [forcedeth_tmp_adv]:8, [forcedeth_tmp_lpa]:8
866 shurf 2495
 
2288 clevermous 2496
        ; FIXME: handle parallel detection properly, handle gigabit ethernet
2497
        ; lpa = lpa & adv
2498
        mov     eax, dword [forcedeth_tmp_adv]
2499
        and     dword [forcedeth_tmp_lpa], eax
866 shurf 2500
 
2288 clevermous 2501
        mov     eax, dword [forcedeth_tmp_lpa]
866 shurf 2502
 
2288 clevermous 2503
        ; if (lpa & LPA_100FULL) {
2504
        test    eax, LPA_100FULL
2505
        jz      @f
2506
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100
2507
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100)
2508
        ; newdup = 1
2509
        mov     dword [forcedeth_tmp_newdup], 1
2510
        jmp     .set_speed
866 shurf 2511
@@:
2288 clevermous 2512
        ; } else if (lpa & LPA_100HALF) {
2513
        test    eax, LPA_100HALF
2514
        jz      @f
2515
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100
2516
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100)
2517
        ; newdup = 0
2518
        mov     dword [forcedeth_tmp_newdup], 0
2519
        jmp     .set_speed
866 shurf 2520
@@:
2288 clevermous 2521
        ; } else if (lpa & LPA_10FULL) {
2522
        test    eax, LPA_10FULL
2523
        jz      @f
2524
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
2525
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
2526
        ; newdup = 1
2527
        mov     dword [forcedeth_tmp_newdup], 1
2528
        jmp     .set_speed
866 shurf 2529
@@:
2288 clevermous 2530
        ; } else if (lpa & LPA_10HALF) {
2531
        test    eax, LPA_10HALF
2532
        ;    newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
2533
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
2534
        ;    newdup = 0;
2535
        mov     dword [forcedeth_tmp_newdup], 0
2536
        jmp     .set_speed
866 shurf 2537
@@:
2288 clevermous 2538
        ; } else {
2539
        ; printf("bad ability %hX - falling back to 10HD.\n", lpa)
2540
        DEBUGF 1," K : FORCEDETH: update_linkspeed: bad ability 0x%x - falling back to 10HD.\n", eax
866 shurf 2541
 
2288 clevermous 2542
        ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
2543
        mov     dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
2544
        ; newdup = 0
2545
        mov     dword [forcedeth_tmp_newdup], 0
2546
        ; }
866 shurf 2547
 
2548
.set_speed:
2549
 
2288 clevermous 2550
        ; if (np->duplex == newdup && np->linkspeed == newls)
2551
        mov     eax, dword [forcedeth_tmp_newdup]
2552
        cmp     eax, dword [forcedeth_duplex]
2553
        jne     .end_if2
2554
        mov     eax, dword [forcedeth_tmp_newls]
2555
        cmp     eax, dword [forcedeth_linkspeed]
2556
        jne     .end_if2
2557
        ;    return retval;
2558
        jmp     .return
2559
 
866 shurf 2560
.end_if2:
2561
 
2288 clevermous 2562
        ; dprintf(("changing link setting from %d/%s to %d/%s.\n",
2563
        ;    np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex"))
2564
        DEBUGF 1," K : FORCEDETH: update_linkspeed: changing link from %x/XD to %x/XD.\n", [forcedeth_linkspeed]:8, [forcedeth_tmp_newls]:8     ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!
866 shurf 2565
 
2288 clevermous 2566
        ; np->duplex = newdup
2567
        mov     eax, dword [forcedeth_tmp_newdup]
2568
        mov     dword [forcedeth_duplex], eax
866 shurf 2569
 
2288 clevermous 2570
        ; np->linkspeed = newls
2571
        mov     eax, [forcedeth_tmp_newls]
2572
        mov     dword [forcedeth_linkspeed], eax
866 shurf 2573
 
2288 clevermous 2574
        ; if (np->gigabit == PHY_GIGABIT) {
2575
        cmp     dword [forcedeth_gigabit], PHY_GIGABIT
2576
        jne     .end_if3
866 shurf 2577
 
2288 clevermous 2578
        ; phyreg = readl(base + NvRegRandomSeed);
2579
        mov     edi, dword [forcedeth_mapio_addr]
2580
        mov     eax, dword [edi+NvRegRandomSeed]
866 shurf 2581
 
2288 clevermous 2582
        ; phyreg &= ~(0x3FF00);
2583
        and     eax, not (0x3FF00)
2584
        mov     ecx, eax                ; phyreg = ecx
866 shurf 2585
 
2288 clevermous 2586
        ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10)
2587
        mov     eax, dword [forcedeth_linkspeed]
2588
        and     eax, 0xFFF
2589
        cmp     eax, NVREG_LINKSPEED_10
2590
        jne     @f
2591
        ; phyreg |= NVREG_RNDSEED_FORCE3
2592
        or      ecx, NVREG_RNDSEED_FORCE3
2593
        jmp     .end_if4
866 shurf 2594
@@:
2288 clevermous 2595
        ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
2596
        cmp     eax, NVREG_LINKSPEED_100
2597
        jne     @f
2598
        ; phyreg |= NVREG_RNDSEED_FORCE2
2599
        or      ecx, NVREG_RNDSEED_FORCE2
2600
        jmp     .end_if4
866 shurf 2601
@@:
2288 clevermous 2602
        ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
2603
        cmp     eax, NVREG_LINKSPEED_1000
2604
        jne     .end_if4
2605
        ; phyreg |= NVREG_RNDSEED_FORCE
2606
        or      ecx, NVREG_RNDSEED_FORCE
866 shurf 2607
.end_if4:
2288 clevermous 2608
        ; writel(phyreg, base + NvRegRandomSeed)
2609
        mov     dword [edi+NvRegRandomSeed], ecx
866 shurf 2610
 
2611
.end_if3:
2612
 
2288 clevermous 2613
        ; phyreg = readl(base + NvRegPhyInterface)
2614
        mov     ecx, dword [edi+NvRegPhyInterface]
866 shurf 2615
 
2288 clevermous 2616
        ; phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000)
2617
        and     ecx, not (PHY_HALF or PHY_100 or PHY_1000)
2618
 
2619
        ; if (np->duplex == 0)
2620
        cmp     dword [forcedeth_duplex], 0
2621
        jne     @f
2622
        ; phyreg |= PHY_HALF
2623
        or      ecx, PHY_HALF
866 shurf 2624
@@:
2288 clevermous 2625
        ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
2626
        mov     eax, dword [forcedeth_linkspeed]
2627
        and     eax, 0xFFF
2628
        cmp     eax, NVREG_LINKSPEED_100
2629
        jne     @f
2630
        ; phyreg |= PHY_100
2631
        or      ecx, PHY_100
2632
        jmp     .end_if5
866 shurf 2633
@@:
2288 clevermous 2634
        ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
2635
        cmp     eax, NVREG_LINKSPEED_1000
2636
        jne     .end_if5
2637
        ; phyreg |= PHY_1000
2638
        or      ecx, PHY_1000
866 shurf 2639
 
2640
.end_if5:
2641
 
2288 clevermous 2642
        ; writel(phyreg, base + NvRegPhyInterface)
2643
        mov     dword [edi+NvRegPhyInterface], ecx
866 shurf 2644
 
2288 clevermous 2645
        ; writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1);
2646
        cmp     dword [forcedeth_duplex], 0
2647
        je      @f
2648
        mov     ecx, 0
2649
        jmp     .next
866 shurf 2650
@@:
2288 clevermous 2651
        mov     ecx, NVREG_MISC1_HD
866 shurf 2652
.next:
2288 clevermous 2653
        or      ecx, NVREG_MISC1_FORCE
2654
        mov     dword [edi+NvRegMisc1], ecx
866 shurf 2655
 
2288 clevermous 2656
        ; pci_push(base)
2657
        call    forcedeth_pci_push
866 shurf 2658
 
2288 clevermous 2659
        ; writel(np->linkspeed, base + NvRegLinkSpeed)
2660
        mov     eax, dword [forcedeth_linkspeed]
2661
        mov     dword [edi+NvRegLinkSpeed], eax
866 shurf 2662
 
2288 clevermous 2663
        ; pci_push(base)
2664
        call    forcedeth_pci_push
866 shurf 2665
 
2666
.return:
2288 clevermous 2667
        ; return retval
2668
        mov     eax, dword [forcedeth_tmp_retval]
2669
        pop     edi esi ecx ebx
2670
        ret
866 shurf 2671
 
2288 clevermous 2672
 
866 shurf 2673
; Input:  none
2674
; Output: none
2675
forcedeth_start_tx:
2288 clevermous 2676
        push    edi
2677
        ; dprintf(("start_tx\n"))
2678
        DEBUGF 1," K : FORCEDETH: start_tx.\n"
866 shurf 2679
 
2288 clevermous 2680
        ; writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl)
2681
        mov     edi, dword [forcedeth_mapio_addr]
2682
        mov     dword [edi+NvRegTransmitterControl], NVREG_XMITCTL_START
866 shurf 2683
 
2288 clevermous 2684
        ; pci_push(base)
2685
        call    forcedeth_pci_push
866 shurf 2686
 
2687
.return:
2288 clevermous 2688
        pop     edi
2689
        ret
866 shurf 2690
 
2691
; Interrupt handler
2692
forcedeth_int_handler:
2288 clevermous 2693
        DEBUGF 1," K : FORCEDETH: interrupt handler.\n"
866 shurf 2694
 
2288 clevermous 2695
        ret
2696