Rev 866 | 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: 867 $ |
||
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 | |||
45 | PCI_REG_COMMAND equ 0x04 ; command register |
||
46 | |||
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 |
||
50 | |||
51 | PCI_VENDOR_ID equ 0x00 ; 16 bit |
||
52 | PCI_REVISION_ID equ 0x08 ; 8 bits |
||
53 | |||
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 |
||
60 | |||
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) |
||
64 | |||
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 |
||
69 | |||
70 | ; NIC specific static variables go here |
||
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 |
||
86 | |||
87 | ETH_DATA_LEN equ 1500 |
||
88 | |||
89 | ; rx/tx mac addr + type + vlan + align + slack |
||
90 | RX_NIC_BUFSIZE equ (ETH_DATA_LEN + 64) |
||
91 | ; even more slack |
||
92 | RX_ALLOC_BUFSIZE equ (ETH_DATA_LEN + 128) |
||
93 | |||
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 |
||
133 | |||
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 |
||
140 | |||
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 |
||
148 | |||
149 | NVREG_MIISPEED_BIT8 equ (1 shl 8) |
||
150 | NVREG_MIIDELAY equ 5 |
||
151 | |||
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 |
||
158 | |||
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) |
||
162 | |||
163 | NVREG_IRQSTAT_MASK equ 0x1ff |
||
164 | |||
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 |
||
171 | |||
172 | NVREG_MCASTADDRA_FORCE equ 0x01 |
||
173 | |||
174 | NVREG_MAC_RESET_ASSERT equ 0x0F3 |
||
175 | |||
176 | NVREG_MISC1_HD equ 0x02 |
||
177 | NVREG_MISC1_FORCE equ 0x3b0f3c |
||
178 | |||
179 | NVREG_PFF_ALWAYS equ 0x7F0008 |
||
180 | NVREG_PFF_PROMISC equ 0x80 |
||
181 | NVREG_PFF_MYADDR equ 0x20 |
||
182 | |||
183 | NVREG_OFFLOAD_HOMEPHY equ 0x601 |
||
184 | NVREG_OFFLOAD_NORMAL equ RX_NIC_BUFSIZE |
||
185 | |||
186 | NVREG_RNDSEED_MASK equ 0x00ff |
||
187 | NVREG_RNDSEED_FORCE equ 0x7f00 |
||
188 | NVREG_RNDSEED_FORCE2 equ 0x2d00 |
||
189 | NVREG_RNDSEED_FORCE3 equ 0x7400 |
||
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 |
||
193 | NVREG_POLL_DEFAULT equ 970 |
||
194 | |||
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 |
||
200 | |||
201 | NVREG_WAKEUPFLAGS_VAL equ 0x7770 |
||
202 | |||
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 |
||
210 | |||
211 | NVREG_POWERSTATE2_POWERUP_MASK equ 0x0F11 |
||
212 | NVREG_POWERSTATE2_POWERUP_REV_A3 equ 0x0001 |
||
213 | |||
214 | NVREG_RCVCTL_START equ 0x01 |
||
215 | NVREG_RCVSTAT_BUSY equ 0x01 |
||
216 | |||
217 | NVREG_XMITCTL_START equ 0x01 |
||
218 | |||
219 | NVREG_LINKSPEED_FORCE equ 0x10000 |
||
220 | NVREG_LINKSPEED_10 equ 1000 |
||
221 | NVREG_LINKSPEED_100 equ 100 |
||
222 | NVREG_LINKSPEED_1000 equ 50 |
||
223 | |||
224 | NVREG_RINGSZ_TXSHIFT equ 0 |
||
225 | NVREG_RINGSZ_RXSHIFT equ 16 |
||
226 | |||
227 | LPA_1000FULL equ 0x0800 |
||
228 | |||
229 | ; Link partner ability register. |
||
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 |
||
240 | |||
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 |
||
251 | |||
252 | ; PHY defines |
||
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 |
||
266 | |||
267 | PHY_TIMEOUT equ 0x1 |
||
268 | PHY_ERROR equ 0x2 |
||
269 | |||
270 | PHY_100 equ 0x1 |
||
271 | PHY_1000 equ 0x2 |
||
272 | PHY_HALF equ 0x100 |
||
273 | |||
274 | PHY_RGMII equ 0x10000000 |
||
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. |
||
281 | DESC_VER_1 equ 0x0 |
||
282 | DESC_VER_2 equ (0x02100 or NVREG_TXRXCTL_RXCHECK) |
||
283 | |||
284 | MAC_ADDR_LEN equ 6 |
||
285 | |||
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) |
||
295 | |||
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) |
||
303 | ; error and valid are the same for both |
||
304 | NV_TX2_ERROR equ (1 shl 30) |
||
305 | NV_TX2_VALID equ (1 shl 31) |
||
306 | |||
307 | NV_RX_DESCRIPTORVALID equ (1 shl 16) |
||
308 | NV_RX_AVAIL equ (1 shl 31) |
||
309 | |||
310 | NV_RX2_DESCRIPTORVALID equ (1 shl 29) |
||
311 | |||
312 | RX_RING equ 4 |
||
313 | TX_RING equ 2 |
||
314 | |||
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) |
||
319 | |||
320 | ; Miscelaneous hardware related defines: |
||
321 | NV_PCI_REGSZ_VER1 equ 0x270 |
||
322 | NV_PCI_REGSZ_VER2 equ 0x604 |
||
323 | ; various timeout delays: all in usec |
||
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 |
||
341 | |||
342 | ; Advertisement control register. |
||
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 |
||
354 | |||
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) |
||
357 | |||
358 | MII_1000BT_CR equ 0x09 |
||
359 | MII_1000BT_SR equ 0x0a |
||
360 | ADVERTISE_1000FULL equ 0x0200 |
||
361 | ADVERTISE_1000HALF equ 0x0100 |
||
362 | |||
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 |
||
368 | |||
369 | ; Basic mode status register. |
||
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 |
||
382 | |||
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 |
||
387 | |||
388 | uglobal |
||
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 |
||
413 | endg |
||
414 | |||
415 | struc forcedeth_TxDesc { |
||
416 | .PacketBuffer dd ? |
||
417 | .FlagLen dd ? |
||
418 | } |
||
419 | virtual at 0 |
||
420 | forcedeth_TxDesc forcedeth_TxDesc |
||
421 | sizeof.forcedeth_TxDesc = $ - forcedeth_TxDesc |
||
422 | end virtual |
||
423 | |||
424 | struc forcedeth_RxDesc { |
||
425 | .PacketBuffer dd ? |
||
426 | .FlagLen dd ? |
||
427 | } |
||
428 | virtual at 0 |
||
429 | forcedeth_RxDesc forcedeth_RxDesc |
||
430 | sizeof.forcedeth_RxDesc = $ - forcedeth_RxDesc |
||
431 | end virtual |
||
432 | |||
433 | virtual at eth_data_start |
||
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 |
||
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 | |||
465 | ; 1) erase previous misconfiguration |
||
466 | ; 4.1-1: stop adapter: ignored, 4.3 seems to be overkill |
||
467 | |||
468 | ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) |
||
469 | mov edi, dword [forcedeth_mapio_addr] |
||
470 | mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
||
471 | |||
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 |
||
480 | |||
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 |
||
489 | |||
490 | ; writel(0, base + NvRegAdapterControl) |
||
491 | mov dword [edi+NvRegAdapterControl], 0 |
||
492 | |||
493 | |||
494 | ; 2) initialize descriptor rings |
||
495 | ; init_ring(nic) |
||
496 | call forcedeth_init_ring |
||
497 | |||
498 | ; writel(0, base + NvRegLinkSpeed) |
||
499 | mov dword [edi+NvRegLinkSpeed], 0 |
||
500 | |||
501 | ; writel(0, base + NvRegUnknownTransmitterReg) |
||
502 | mov dword [edi+NvRegUnknownTransmitterReg], 0 |
||
503 | |||
504 | ; txrx_reset(nic) |
||
505 | call forcedeth_txrx_reset |
||
506 | |||
507 | ; writel(0, base + NvRegUnknownSetupReg6) |
||
508 | mov dword [edi+NvRegUnknownSetupReg6], 0 |
||
509 | |||
510 | ; np->in_shutdown = 0 |
||
511 | mov dword [forcedeth_in_shutdown], 0 |
||
512 | |||
513 | |||
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 |
||
522 | |||
523 | |||
524 | ; 4) give hw rings |
||
525 | ; writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr) |
||
526 | mov eax, forcedeth_rx_ring |
||
527 | |||
528 | ;DEBUGF 1," K : FORCEDETH: rx_ring at 0x%x\n", eax |
||
529 | |||
530 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
531 | mov dword [edi+NvRegRxRingPhysAddr], eax |
||
532 | |||
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 |
||
537 | |||
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)) |
||
540 | |||
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 |
||
547 | |||
548 | ; writel(np->linkspeed, base + NvRegLinkSpeed) |
||
549 | mov dword [edi+NvRegLinkSpeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
550 | |||
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 |
||
564 | |||
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 ;;;;;;;;;;;;;;;;;;;;;; |
||
569 | |||
570 | ; writel(0, base + NvRegUnknownSetupReg4) |
||
571 | mov dword [edi+NvRegUnknownSetupReg4], 0 |
||
572 | |||
573 | ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) |
||
574 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 |
||
575 | |||
576 | |||
577 | ; printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half") |
||
578 | ;;;;;;;;;;; DEBUGF |
||
579 | |||
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 |
||
588 | |||
589 | ; writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags) |
||
590 | mov dword [edi+NvRegPacketFilterFlags], NVREG_PFF_ALWAYS |
||
591 | |||
592 | ; writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig) |
||
593 | mov dword [edi+NvRegOffloadConfig], NVREG_OFFLOAD_NORMAL |
||
594 | |||
595 | ; writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus) |
||
596 | mov eax, dword [edi+NvRegReceiverStatus] |
||
597 | mov dword [edi+NvRegReceiverStatus], eax |
||
598 | |||
599 | ; Get a random number |
||
600 | ; i = random() |
||
601 | push edi |
||
602 | stdcall sys_clock ; eax = 0x00SSMMHH (current system time) |
||
603 | pop edi |
||
604 | |||
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 |
||
609 | |||
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 |
||
621 | |||
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) |
||
631 | |||
632 | ; writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4) |
||
633 | mov dword [edi+NvRegUnknownSetupReg4], NVREG_UNKSETUP4_VAL |
||
634 | |||
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] |
||
640 | |||
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 |
||
647 | |||
648 | @@: |
||
649 | |||
650 | ; pci_push(base) |
||
651 | call forcedeth_pci_push |
||
652 | |||
653 | ; nv_udelay(10) |
||
654 | mov esi, 10 |
||
655 | call forcedeth_nv_udelay |
||
656 | |||
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 |
||
661 | |||
662 | ; ??? disable all interrupts ??? |
||
663 | ; writel(0, base + NvRegIrqMask) |
||
664 | mov dword [edi+NvRegIrqMask], 0 |
||
665 | |||
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 |
||
675 | |||
676 | ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) |
||
677 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 |
||
678 | |||
679 | ; writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus) |
||
680 | mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK |
||
681 | |||
682 | ; pci_push(base) |
||
683 | call forcedeth_pci_push |
||
684 | |||
685 | |||
686 | ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) |
||
687 | mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
||
688 | |||
689 | ; writel(0, base + NvRegMulticastAddrB) |
||
690 | mov dword [edi+NvRegMulticastAddrB], 0 |
||
691 | |||
692 | ; writel(0, base + NvRegMulticastMaskA) |
||
693 | mov dword [edi+NvRegMulticastMaskA], 0 |
||
694 | |||
695 | ; writel(0, base + NvRegMulticastMaskB) |
||
696 | mov dword [edi+NvRegMulticastMaskB], 0 |
||
697 | |||
698 | ; writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags) |
||
699 | mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_ALWAYS or NVREG_PFF_MYADDR) |
||
700 | |||
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(). |
||
706 | |||
707 | ; miistat = readl(base + NvRegMIIStatus) |
||
708 | mov eax, dword [edi+NvRegMIIStatus] |
||
709 | |||
710 | ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
||
711 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK |
||
712 | |||
713 | ; dprintf(("startup: got 0x%hX.\n", miistat)); |
||
714 | ;;; DEBUGF 1," K : FORCEDETH: startup: got 0x%x\n", eax |
||
715 | |||
716 | |||
717 | ; ret = update_linkspeed(nic) |
||
718 | call forcedeth_update_linkspeed |
||
719 | push eax |
||
720 | |||
721 | ; start_tx(nic) |
||
722 | call forcedeth_start_tx |
||
723 | |||
724 | pop eax |
||
725 | |||
726 | ; if (ret) { |
||
727 | ; //Start Connection netif_carrier_on(dev); |
||
728 | ; } else { |
||
729 | ; printf("no link during initialization.\n"); |
||
730 | ; } |
||
731 | |||
732 | ;*** added by shurf (21.09.2008) |
||
733 | mov dword [forcedeth_nocable], 0 |
||
734 | ;*** |
||
735 | |||
736 | test eax, eax |
||
737 | jnz .return |
||
738 | DEBUGF 1," K : FORCEDETH: no link during initialization.\n" |
||
739 | |||
740 | ;*** added by shurf (21.09.2008) |
||
741 | mov dword [forcedeth_nocable], 1 |
||
742 | ;*** |
||
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 |
||
749 | ret |
||
750 | |||
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 | |||
763 | ; DEBUGF 1," K : FORCEDETH: 0x%x 0x%x, 0x%x\n", [io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
||
764 | |||
765 | mov dword [forcedeth_needs_mac_reset], 0 |
||
766 | |||
767 | ; BEGIN of adjust_pci_device() |
||
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 |
||
787 | |||
788 | ; Check latency settings |
||
789 | @@: |
||
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 |
||
796 | |||
797 | ; see if its at least 32 |
||
798 | cmp al, 32 |
||
799 | jge @f |
||
800 | ; set latency to 32 |
||
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" |
||
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 |
||
809 | ; END of adjust_pci_device() |
||
810 | |||
811 | @@: |
||
812 | ; BEGIN of pci_bar_start (addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0)) |
||
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 | @@: push eax |
||
823 | and eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK |
||
824 | cmp eax, PCI_BASE_ADDRESS_MEM_TYPE_64 |
||
825 | jne .not64 |
||
826 | mov al, 2 ; dword |
||
827 | mov bh, [pci_dev] |
||
828 | mov ah, [pci_bus] |
||
829 | mov bl, PCI_BASE_ADDRESS_0 + 4 |
||
830 | call pci_read_reg |
||
831 | or eax, eax |
||
832 | jz .not64 |
||
833 | DEBUGF 1,"K : FORCEDETH: pci_bar_start: Unhandled 64bit BAR\n" |
||
834 | or eax, -1 |
||
835 | jmp .next |
||
836 | .not64: |
||
837 | pop eax |
||
838 | and eax, PCI_BASE_ADDRESS_MEM_MASK |
||
839 | .next: |
||
840 | ; END of pci_bar_start |
||
841 | ; addr = eax |
||
842 | mov dword [forcedeth_mmio_addr], eax |
||
843 | |||
844 | |||
845 | ; BEGIN of pci_bar_size (sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0)) |
||
846 | |||
847 | ; Save original bar |
||
848 | mov al, 2 ; dword |
||
849 | mov bh, [pci_dev] |
||
850 | mov ah, [pci_bus] |
||
851 | mov bl, PCI_BASE_ADDRESS_0 |
||
852 | call pci_read_reg |
||
853 | mov dword [forcedeth_tmp_start], eax |
||
854 | ; Compute which bits can be set |
||
855 | ; (ecx - value to write) |
||
856 | mov al, 2 ; dword |
||
857 | mov bh, [pci_dev] |
||
858 | mov ah, [pci_bus] |
||
859 | mov bl, PCI_BASE_ADDRESS_0 |
||
860 | mov ecx, (not 0) |
||
861 | call pci_write_reg |
||
862 | mov al, 2 ; dword |
||
863 | mov bh, [pci_dev] |
||
864 | mov ah, [pci_bus] |
||
865 | mov bl, PCI_BASE_ADDRESS_0 |
||
866 | call pci_read_reg |
||
867 | push eax |
||
868 | ; Restore the original size |
||
869 | mov al, 2 ; dword |
||
870 | mov bh, [pci_dev] |
||
871 | mov ah, [pci_bus] |
||
872 | mov bl, PCI_BASE_ADDRESS_0 |
||
873 | mov ecx, dword [forcedeth_tmp_start] |
||
874 | call pci_write_reg |
||
875 | ; Find the significant bits |
||
876 | pop eax |
||
877 | test dword [forcedeth_tmp_start], PCI_BASE_ADDRESS_SPACE_IO |
||
878 | jz @f |
||
879 | and eax, PCI_BASE_ADDRESS_IO_MASK |
||
880 | jmp .next2 |
||
881 | @@: and eax, PCI_BASE_ADDRESS_MEM_MASK |
||
882 | .next2: |
||
883 | ; Find the lowest bit set |
||
884 | mov ecx, eax |
||
885 | sub eax, 1 |
||
886 | not eax |
||
887 | and ecx, eax |
||
888 | |||
889 | ; END of pci_bar_start |
||
890 | mov dword [forcedeth_mmio_size], ecx |
||
891 | |||
892 | DEBUGF 1," K : FORCEDETH: mmio_addr= 0x%x [mmio_size= 0x%x]\n", [forcedeth_mmio_addr]:8, [forcedeth_mmio_size]:8 |
||
893 | |||
894 | ; Get Vendor and Device ID |
||
895 | mov al, 2 |
||
896 | mov bh, [pci_dev] |
||
897 | mov ah, [pci_bus] |
||
898 | mov bl, PCI_VENDOR_ID |
||
899 | call pci_read_reg |
||
900 | mov word [forcedeth_vendor_id], ax |
||
901 | shr eax, 16 |
||
902 | mov word [forcedeth_device_id], ax |
||
903 | |||
904 | DEBUGF 1," K : FORCEDETH: vendor_id= 0x%x device_id= 0x%x\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 |
||
905 | |||
906 | ; handle different descriptor versions |
||
907 | mov eax, dword [forcedeth_device_id] |
||
908 | cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_1 |
||
909 | je .ver1 |
||
910 | cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_2 |
||
911 | je .ver1 |
||
912 | cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_3 |
||
913 | je .ver1 |
||
914 | mov dword [forcedeth_desc_ver], DESC_VER_2 |
||
915 | jmp @f |
||
916 | .ver1: mov dword [forcedeth_desc_ver], DESC_VER_1 |
||
917 | @@: |
||
918 | ; read the mac address |
||
919 | ; map memory |
||
920 | stdcall map_io_mem, [forcedeth_mmio_addr], [forcedeth_mmio_size], (PG_SW+PG_NOCACHE) |
||
921 | test eax, eax |
||
922 | jz .fail |
||
923 | |||
924 | mov dword [forcedeth_mapio_addr], eax |
||
925 | mov edi, eax |
||
926 | mov eax, dword [edi+NvRegMacAddrA] |
||
927 | mov dword [forcedeth_orig_mac0], eax |
||
928 | mov eax, dword [edi+NvRegMacAddrB] |
||
929 | mov dword [forcedeth_orig_mac1], eax |
||
930 | |||
931 | ; save MAC-address to global variable node_addr |
||
932 | mov ecx, MAC_ADDR_LEN |
||
933 | xor ebx, ebx |
||
934 | mov edx, forcedeth_orig_mac0 |
||
935 | add edx, (MAC_ADDR_LEN-1) |
||
936 | @@: mov al, byte [edx] |
||
937 | mov byte [node_addr+ebx], al |
||
938 | inc ebx |
||
939 | dec edx |
||
940 | loop @b |
||
941 | |||
942 | ; DEBUGF 1," K : FORCEDETH: orig_mac0= 0x%x\n", [forcedeth_orig_mac0]:8 |
||
943 | ; DEBUGF 1," K : FORCEDETH: orig_mac1= 0x%x\n", [forcedeth_orig_mac1]:8 |
||
944 | 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, |
||
945 | |||
946 | ; disable WOL |
||
947 | mov edi, dword [forcedeth_mapio_addr] |
||
948 | mov dword [edi+NvRegWakeUpFlags], 0 |
||
949 | mov dword [forcedeth_wolenabled], 0 |
||
950 | |||
951 | mov dword [forcedeth_txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID) |
||
952 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
953 | jne @f |
||
954 | mov dword [forcedeth_txflags], (NV_TX_LASTPACKET or NV_TX_VALID) |
||
955 | @@: |
||
956 | |||
957 | ; BEGIN of switch (pci->dev_id) |
||
958 | |||
959 | cmp word [forcedeth_device_id], 0x01C3 |
||
960 | jne .next_0x0066 |
||
961 | ; nforce |
||
962 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
963 | jmp .end_switch |
||
964 | |||
965 | .next_0x0066: |
||
966 | cmp word [forcedeth_device_id], 0x0066 |
||
967 | je @f |
||
968 | cmp word [forcedeth_device_id], 0x00D6 |
||
969 | je @f |
||
970 | jmp .next_0x0086 |
||
971 | @@: |
||
972 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
973 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
974 | jne @f |
||
975 | or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
||
976 | jmp .end_switch |
||
977 | @@: or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
||
978 | jmp .end_switch |
||
979 | |||
980 | .next_0x0086: |
||
981 | cmp word [forcedeth_device_id], 0x0086 |
||
982 | je @f |
||
983 | cmp word [forcedeth_device_id], 0x008c |
||
984 | je @f |
||
985 | cmp word [forcedeth_device_id], 0x00e6 |
||
986 | je @f |
||
987 | cmp word [forcedeth_device_id], 0x00df |
||
988 | je @f |
||
989 | cmp word [forcedeth_device_id], 0x0056 |
||
990 | je @f |
||
991 | cmp word [forcedeth_device_id], 0x0057 |
||
992 | je @f |
||
993 | cmp word [forcedeth_device_id], 0x0037 |
||
994 | je @f |
||
995 | cmp word [forcedeth_device_id], 0x0038 |
||
996 | je @f |
||
997 | jmp .next_0x0268 |
||
998 | @@: |
||
999 | ; np->irqmask = NVREG_IRQMASK_WANTED_2; |
||
1000 | ; np->irqmask |= NVREG_IRQ_TIMER; |
||
1001 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
1002 | |||
1003 | ; if (np->desc_ver == DESC_VER_1) |
||
1004 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1005 | jne @f |
||
1006 | ; np->tx_flags |= NV_TX_LASTPACKET1; |
||
1007 | or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
||
1008 | jmp .end_switch |
||
1009 | ; else |
||
1010 | @@: |
||
1011 | ; np->tx_flags |= NV_TX2_LASTPACKET1; |
||
1012 | or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
||
1013 | |||
1014 | ; break; |
||
1015 | jmp .end_switch |
||
1016 | |||
1017 | .next_0x0268: |
||
1018 | cmp word [forcedeth_device_id], 0x0268 |
||
1019 | je @f |
||
1020 | cmp word [forcedeth_device_id], 0x0269 |
||
1021 | je @f |
||
1022 | cmp word [forcedeth_device_id], 0x0372 |
||
1023 | je @f |
||
1024 | cmp word [forcedeth_device_id], 0x0373 |
||
1025 | je @f |
||
1026 | jmp .default_switch |
||
1027 | @@: |
||
1028 | ; pci_read_config_byte(pci, PCI_REVISION_ID, &revision_id); |
||
1029 | mov al, 0 ; byte |
||
1030 | mov bh, [pci_dev] |
||
1031 | mov ah, [pci_bus] |
||
1032 | mov bl, PCI_REVISION_ID |
||
1033 | call pci_read_reg |
||
1034 | mov ecx, eax ; cl = revision_id |
||
1035 | |||
1036 | ; take phy and nic out of low power mode |
||
1037 | ; powerstate = readl(base + NvRegPowerState2); |
||
1038 | mov edi, dword [forcedeth_mapio_addr] |
||
1039 | mov eax, dword [edi+NvRegPowerState2] ; eax = powerstate |
||
1040 | |||
1041 | ; powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; |
||
1042 | and eax, not NVREG_POWERSTATE2_POWERUP_MASK |
||
1043 | |||
1044 | ; if ((pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_12||pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_13)&&revision_id>=0xA3) |
||
1045 | cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12 |
||
1046 | je @f |
||
1047 | cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13 |
||
1048 | je @f |
||
1049 | jmp .end_if |
||
1050 | @@: |
||
1051 | cmp cl, 0xA3 |
||
1052 | jl .end_if |
||
1053 | ; powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; |
||
1054 | or eax, NVREG_POWERSTATE2_POWERUP_REV_A3 |
||
1055 | |||
1056 | .end_if: |
||
1057 | |||
1058 | ; writel(powerstate, base + NvRegPowerState2); |
||
1059 | mov dword [edi+NvRegPowerState2], eax |
||
1060 | |||
1061 | ; //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ |
||
1062 | ; np->irqmask = NVREG_IRQMASK_WANTED_2; |
||
1063 | ; np->irqmask |= NVREG_IRQ_TIMER; |
||
1064 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
1065 | |||
1066 | ; needs_mac_reset = 1; |
||
1067 | mov dword [forcedeth_needs_mac_reset], 1 |
||
1068 | |||
1069 | ; if (np->desc_ver == DESC_VER_1) |
||
1070 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1071 | jne @f |
||
1072 | ; np->tx_flags |= NV_TX_LASTPACKET1; |
||
1073 | or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
||
1074 | jmp .end_if2 |
||
1075 | @@: |
||
1076 | ; else |
||
1077 | ; np->tx_flags |= NV_TX2_LASTPACKET1; |
||
1078 | or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
||
1079 | |||
1080 | .end_if2: |
||
1081 | ; break; |
||
1082 | jmp .end_switch |
||
1083 | |||
1084 | .default_switch: |
||
1085 | DEBUGF 1," K : FORCEDETH: Your card was undefined in this driver.\n" |
||
1086 | DEBUGF 1," K : FORCEDETH: Review driver_data in Kolibri driver and send a patch\n" |
||
1087 | |||
1088 | .end_switch: |
||
1089 | |||
1090 | ; END of switch (pci->dev_id) |
||
1091 | |||
1092 | |||
1093 | ; Find a suitable phy |
||
1094 | mov dword [forcedeth_tmp_i], 1 |
||
1095 | .for_loop: |
||
1096 | ; for (i = 1; i <= 32; i++) |
||
1097 | ; phyaddr = i & 0x1f |
||
1098 | mov ebx, dword [forcedeth_tmp_i] |
||
1099 | and ebx, 0x1f |
||
1100 | |||
1101 | ; id1 = mii_rw(phyaddr, MII_PHYSID1, MII_READ) |
||
1102 | ;EBX - addr, EAX - miireg, ECX - value |
||
1103 | mov eax, MII_PHYSID1 |
||
1104 | mov ecx, MII_READ |
||
1105 | call forcedeth_mii_rw ; id1 = eax |
||
1106 | |||
1107 | ; if (id1 < 0 || id1 == 0xffff) |
||
1108 | cmp eax, 0xffffffff |
||
1109 | je .continue_for |
||
1110 | test eax, 0x80000000 |
||
1111 | jnz .continue_for |
||
1112 | mov dword [forcedeth_tmp_id1], eax |
||
1113 | |||
1114 | ; id2 = mii_rw(nic, phyaddr, MII_PHYSID2, MII_READ) |
||
1115 | mov eax, MII_PHYSID2 |
||
1116 | mov ecx, MII_READ |
||
1117 | call forcedeth_mii_rw ; id2 = eax |
||
1118 | |||
1119 | ; if (id2 < 0 || id2 == 0xffff) |
||
1120 | cmp eax, 0xffffffff |
||
1121 | je .continue_for |
||
1122 | test eax, 0x80000000 |
||
1123 | jnz .continue_for |
||
1124 | mov dword [forcedeth_tmp_id2], eax |
||
1125 | |||
1126 | jmp .break_for |
||
1127 | .continue_for: |
||
1128 | inc dword [forcedeth_tmp_i] |
||
1129 | cmp dword [forcedeth_tmp_i], 32 |
||
1130 | jle .for_loop |
||
1131 | jmp .end_for |
||
1132 | |||
1133 | .break_for: |
||
1134 | |||
1135 | ;;;; DEBUGF 1," K : FORCEDETH: id1=0x%x id2=0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8 |
||
1136 | |||
1137 | ; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT |
||
1138 | mov eax, dword [forcedeth_tmp_id1] |
||
1139 | and eax, PHYID1_OUI_MASK |
||
1140 | shl eax, PHYID1_OUI_SHFT |
||
1141 | mov dword [forcedeth_tmp_id1], eax |
||
1142 | |||
1143 | ; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT |
||
1144 | mov eax, dword [forcedeth_tmp_id2] |
||
1145 | and eax, PHYID2_OUI_MASK |
||
1146 | shr eax, PHYID2_OUI_SHFT |
||
1147 | mov dword [forcedeth_tmp_id2], eax |
||
1148 | |||
1149 | DEBUGF 1," K : FORCEDETH: Found PHY 0x%x:0x%x at address 0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8, ebx |
||
1150 | |||
1151 | ; np->phyaddr = phyaddr; |
||
1152 | mov dword [forcedeth_phyaddr], ebx |
||
1153 | |||
1154 | ; np->phy_oui = id1 | id2; |
||
1155 | mov eax, dword [forcedeth_tmp_id1] |
||
1156 | or eax, dword [forcedeth_tmp_id2] |
||
1157 | mov dword [forcedeth_phy_oui], eax |
||
1158 | |||
1159 | .end_for: |
||
1160 | |||
1161 | ; if (i == 33) |
||
1162 | cmp dword [forcedeth_tmp_i], 33 |
||
1163 | jne @f |
||
1164 | ; PHY in isolate mode? No phy attached and user wants to |
||
1165 | ; test loopback? Very odd, but can be correct. |
||
1166 | |||
1167 | DEBUGF 1," K : FORCEDETH: Could not find a valid PHY.\n" |
||
1168 | |||
1169 | jmp .next3 |
||
1170 | |||
1171 | @@: |
||
1172 | |||
1173 | ; if (i != 33) |
||
1174 | ; reset it |
||
1175 | call forcedeth_phy_init |
||
1176 | |||
1177 | .next3: |
||
1178 | |||
1179 | ; dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n", |
||
1180 | ; pci->name, pci->vendor, pci->dev_id, pci->name)); |
||
1181 | DEBUGF 1," K : FORCEDETH: subsystem: 0x%x:0x%x bound to forcedeth\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 |
||
1182 | |||
1183 | |||
1184 | ; if(needs_mac_reset) mac_reset(nic); |
||
1185 | cmp dword [forcedeth_needs_mac_reset], 0 |
||
1186 | je @f |
||
1187 | call forcedeth_mac_reset |
||
1188 | |||
1189 | @@: |
||
1190 | |||
1191 | ; if(!forcedeth_reset(nic)) return 0; // no valid link |
||
1192 | call forcedeth_reset |
||
1193 | test eax, eax |
||
1194 | jnz @f |
||
1195 | mov eax, 0 |
||
1196 | jmp .return |
||
1197 | |||
1198 | @@: |
||
1199 | |||
1200 | ; point to NIC specific routines |
||
1201 | ; dev->disable = forcedeth_disable; |
||
1202 | ; nic->poll = forcedeth_poll; |
||
1203 | ; nic->transmit = forcedeth_transmit; |
||
1204 | ; nic->irq = forcedeth_irq; |
||
1205 | ;;;;;;;;;stdcall attach_int_handler, 11, forcedeth_int_handler, 0 |
||
1206 | |||
1207 | ; return 1 |
||
1208 | mov eax, 1 |
||
1209 | jmp .return |
||
1210 | |||
1211 | .fail: |
||
1212 | mov eax, 0 |
||
1213 | |||
1214 | .return: |
||
1215 | ret |
||
1216 | |||
1217 | uglobal |
||
1218 | forcedeth_tmp_start dd ? |
||
1219 | forcedeth_tmp_reg dd ? |
||
1220 | forcedeth_tmp_i dd ? |
||
1221 | forcedeth_tmp_id1 dd ? |
||
1222 | forcedeth_tmp_id2 dd ? |
||
1223 | forcedeth_tmp_phyinterface dd ? |
||
1224 | forcedeth_tmp_newls dd ? |
||
1225 | forcedeth_tmp_newdup dd ? |
||
1226 | forcedeth_tmp_retval dd ? |
||
1227 | forcedeth_tmp_control_1000 dd ? |
||
1228 | forcedeth_tmp_lpa dd ? |
||
1229 | forcedeth_tmp_adv dd ? |
||
1230 | forcedeth_tmp_len dd ? |
||
1231 | forcedeth_tmp_valid dd ? |
||
1232 | forcedeth_tmp_nr dd ? |
||
1233 | forcedeth_tmp_ptxb dd ? |
||
1234 | endg |
||
1235 | |||
1236 | ;*************************************************************************** |
||
1237 | ; Function |
||
1238 | ; forcedeth_poll |
||
1239 | ; |
||
1240 | ; Description |
||
1241 | ; Polls the ethernet card for a received packet |
||
1242 | ; Received data, if any, ends up in Ether_buffer |
||
1243 | ; |
||
1244 | ;*************************************************************************** |
||
1245 | forcedeth_poll: |
||
1246 | |||
1247 | mov word [eth_rx_data_len], 0 |
||
1248 | |||
1249 | ; ???????????????????????????? |
||
1250 | ; ??? Clear events? ??? |
||
1251 | mov edi, dword [forcedeth_mapio_addr] |
||
1252 | mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK |
||
1253 | ; ???????????????????????????? |
||
1254 | |||
1255 | .top: |
||
1256 | |||
1257 | ; i = np->cur_rx % RX_RING |
||
1258 | mov eax, dword [forcedeth_cur_rx] |
||
1259 | and eax, (RX_RING-1) |
||
1260 | mov dword [forcedeth_tmp_i], eax |
||
1261 | |||
1262 | ; Flags = le32_to_cpu(rx_ring[i].FlagLen) |
||
1263 | ; Flags = rx_ring[i].FlagLen |
||
1264 | mov cl, sizeof.forcedeth_RxDesc |
||
1265 | mul cl |
||
1266 | add eax, forcedeth_rx_ring |
||
1267 | mov ebx, eax |
||
1268 | mov eax, [ebx + forcedeth_RxDesc.FlagLen] |
||
1269 | |||
1270 | |||
1271 | ; if (Flags & NV_RX_AVAIL) |
||
1272 | test eax, NV_RX_AVAIL |
||
1273 | ; return 0; /* still owned by hardware, */ |
||
1274 | ; still owned by hardware |
||
1275 | jnz .return0 |
||
1276 | |||
1277 | ;;;;; DEBUGF 1,"poll: FlagLen = %x\n", eax |
||
1278 | |||
1279 | ; if (np->desc_ver == DESC_VER_1) { |
||
1280 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1281 | jne @f |
||
1282 | ; if (!(Flags & NV_RX_DESCRIPTORVALID)) |
||
1283 | test eax, NV_RX_DESCRIPTORVALID |
||
1284 | ; return 0; |
||
1285 | jz .return0 |
||
1286 | jmp .next |
||
1287 | ; } else { |
||
1288 | @@: |
||
1289 | ; if (!(Flags & NV_RX2_DESCRIPTORVALID)) |
||
1290 | test eax, NV_RX2_DESCRIPTORVALID |
||
1291 | ; return 0; |
||
1292 | jz .return0 |
||
1293 | ; } |
||
1294 | |||
1295 | .next: |
||
1296 | |||
1297 | ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) |
||
1298 | ; len = rx_ring[i].FlagLen & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); |
||
1299 | ; eax = FlagLen |
||
1300 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1301 | jne @f |
||
1302 | and eax, LEN_MASK_V1 |
||
1303 | jmp .next2 |
||
1304 | @@: |
||
1305 | and eax, LEN_MASK_V2 |
||
1306 | |||
1307 | .next2: |
||
1308 | |||
1309 | ; mov dword [forcedeth_tmp_len], eax |
||
1310 | |||
1311 | ; valid = 1 |
||
1312 | mov dword [forcedeth_tmp_valid], 1 |
||
1313 | |||
1314 | ; got a valid packet - forward it to the network core |
||
1315 | ; nic->packetlen = len; |
||
1316 | mov dword [forcedeth_packetlen], eax |
||
1317 | ; |
||
1318 | mov word [eth_rx_data_len], ax |
||
1319 | ;;;;;;;;; DEBUGF 1,"poll: packet len = 0x%x\n", [forcedeth_packetlen] |
||
1320 | |||
1321 | |||
1322 | ; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen); |
||
1323 | ; Copy packet to system buffer (Ether_buffer) |
||
1324 | ;???? ecx = (len-4) |
||
1325 | mov ecx, eax |
||
1326 | push ecx |
||
1327 | shr ecx, 2 |
||
1328 | |||
1329 | ; rxb + (i * RX_NIC_BUFSIZE) |
||
1330 | mov eax, dword [forcedeth_tmp_i] |
||
1331 | mov bx, RX_NIC_BUFSIZE |
||
1332 | mul bx |
||
1333 | add eax, forcedeth_rxb |
||
1334 | |||
1335 | mov esi, eax |
||
1336 | mov edi, Ether_buffer |
||
1337 | cld ; set to increment |
||
1338 | rep movsd ; mov dword from [esi++] to [edi++] |
||
1339 | pop ecx |
||
1340 | and ecx, 3 ; copy rest 1-3 bytes |
||
1341 | rep movsb |
||
1342 | |||
1343 | ; wmb(); |
||
1344 | ; ??? |
||
1345 | |||
1346 | ; np->cur_rx++; |
||
1347 | inc dword [forcedeth_cur_rx] |
||
1348 | |||
1349 | ; if (!valid) |
||
1350 | cmp dword [forcedeth_tmp_valid], 0 |
||
1351 | jne @f |
||
1352 | ; goto top; |
||
1353 | jmp .top |
||
1354 | @@: |
||
1355 | ; alloc_rx(nic); |
||
1356 | call forcedeth_alloc_rx |
||
1357 | |||
1358 | ; return 1; |
||
1359 | jmp .return1 |
||
1360 | |||
1361 | ;;;;; DEBUGF 1,"K : FORCEDETH: poll: ...\n" |
||
1362 | |||
1363 | |||
1364 | .return0: |
||
1365 | mov eax, 0 |
||
1366 | jmp .return |
||
1367 | .return1: |
||
1368 | mov eax, 1 |
||
1369 | .return: |
||
1370 | ;;push eax |
||
1371 | |||
1372 | ; ???????????????????????????????????????????????? |
||
1373 | ; ????? clear interrupt mask/status |
||
1374 | ; read IRQ status |
||
1375 | ;;mov edi, dword [forcedeth_mapio_addr] |
||
1376 | ;;mov eax, dword [edi+NvRegIrqStatus] |
||
1377 | |||
1378 | ; clear events |
||
1379 | ;;and eax, not (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF or NVREG_IRQ_LINK or NVREG_IRQ_TIMER) |
||
1380 | |||
1381 | ; write IRQ status |
||
1382 | ;;mov dword [edi+NvRegIrqStatus], eax |
||
1383 | ; ???????????????????????????????????????????????? |
||
1384 | |||
1385 | ;;pop eax |
||
1386 | ret |
||
1387 | |||
1388 | |||
1389 | ;*************************************************************************** |
||
1390 | ; Function |
||
1391 | ; forcedeth_transmit |
||
1392 | ; |
||
1393 | ; Description |
||
1394 | ; Transmits a packet of data via the ethernet card |
||
1395 | ; Pointer to 48 bit destination address in edi |
||
1396 | ; Type of packet in bx |
||
1397 | ; size of packet in ecx |
||
1398 | ; pointer to packet data in esi |
||
1399 | ; |
||
1400 | ;*************************************************************************** |
||
1401 | forcedeth_transmit: |
||
1402 | |||
1403 | ; send the packet to destination |
||
1404 | ;pusha |
||
1405 | ;DEBUGF 1,"K : FORCEDETH: transmit: packet type = 0x%x\n", ebx |
||
1406 | ;DEBUGF 1,"K : FORCEDETH: transmit: packet len = 0x%x\n", ecx |
||
1407 | ;mov eax, dword [edi] |
||
1408 | ;DEBUGF 1,"K : FORCEDETH: transmit: dest adr = 0x%x\n", eax |
||
1409 | ;mov eax, dword [edi+4] |
||
1410 | ;DEBUGF 1,"K : FORCEDETH: transmit: dest adr2 = 0x%x\n", eax |
||
1411 | ;mov eax, dword [node_addr] |
||
1412 | ;DEBUGF 1,"K : FORCEDETH: transmit: src adr = 0x%x\n", eax |
||
1413 | ;mov eax, dword [node_addr+4] |
||
1414 | ;DEBUGF 1,"K : FORCEDETH: transmit: src adr2 = 0x%x\n", eax |
||
1415 | ;popa |
||
1416 | |||
1417 | ; int nr = np->next_tx % TX_RING |
||
1418 | mov eax, dword [forcedeth_next_tx] |
||
1419 | and eax, (TX_RING-1) |
||
1420 | mov dword [forcedeth_tmp_nr], eax |
||
1421 | |||
1422 | ; point to the current txb incase multiple tx_rings are used |
||
1423 | ; ptxb = txb + (nr * RX_NIC_BUFSIZE) |
||
1424 | push ecx |
||
1425 | mov cx, RX_NIC_BUFSIZE |
||
1426 | mul cx ; AX*CX, result to DX:AX |
||
1427 | add eax, forcedeth_txb |
||
1428 | mov dword [forcedeth_tmp_ptxb], eax |
||
1429 | push esi |
||
1430 | mov esi, edi ; dst MAC |
||
1431 | mov edi, eax ; packet buffer |
||
1432 | cld ; set to increment |
||
1433 | |||
1434 | ; copy the packet to ring buffer |
||
1435 | ; memcpy(ptxb, d, ETH_ALEN); /* dst */ |
||
1436 | movsd |
||
1437 | movsw |
||
1438 | |||
1439 | ; memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ |
||
1440 | mov esi, node_addr |
||
1441 | movsd |
||
1442 | movsw |
||
1443 | |||
1444 | ; nstype = htons((u16) t); /* type */ |
||
1445 | ; memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ |
||
1446 | mov word [edi], bx |
||
1447 | add edi, 2 |
||
1448 | |||
1449 | ; memcpy(ptxb + ETH_HLEN, p, s); |
||
1450 | pop esi |
||
1451 | pop ecx |
||
1452 | push ecx |
||
1453 | shr ecx, 2 ; count in dwords |
||
1454 | rep movsd ; copy dwords from [esi+=4] to [edi+=4] |
||
1455 | pop ecx |
||
1456 | push ecx |
||
1457 | and ecx, 3 ; copy rest 1-3 bytes |
||
1458 | rep movsb ; copy bytess from [esi++] to [edi++] |
||
1459 | |||
1460 | |||
1461 | ; s += ETH_HLEN; |
||
1462 | ; while (s < ETH_ZLEN) /* pad to min length */ |
||
1463 | ; ptxb[s++] = '\0'; |
||
1464 | ; pad to min length |
||
1465 | pop ecx |
||
1466 | add ecx, ETH_HLEN |
||
1467 | push ecx ; header length + data length |
||
1468 | cmp ecx, ETH_ZLEN |
||
1469 | jge @f |
||
1470 | mov eax, ETH_ZLEN |
||
1471 | sub eax, ecx |
||
1472 | xchg eax, ecx |
||
1473 | mov al, 0 |
||
1474 | rep stosb ; copy byte from al to [edi++] |
||
1475 | |||
1476 | @@: |
||
1477 | |||
1478 | ; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb); |
||
1479 | mov eax, dword [forcedeth_tmp_nr] |
||
1480 | mov cl, sizeof.forcedeth_TxDesc |
||
1481 | mul cl |
||
1482 | add eax, forcedeth_tx_ring |
||
1483 | mov ebx, eax |
||
1484 | mov eax, dword [forcedeth_tmp_ptxb] |
||
1485 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1486 | mov [ebx + forcedeth_TxDesc.PacketBuffer], eax |
||
1487 | |||
1488 | ;DEBUGF 1,"K : FORCEDETH: transmit: PacketBuffer = 0x%x\n", eax |
||
1489 | ;DEBUGF 1,"K : FORCEDETH: transmit: txflags = 0x%x\n", [forcedeth_txflags]:8 |
||
1490 | |||
1491 | ; wmb(); |
||
1492 | ; tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags); |
||
1493 | pop eax ; header length + data length |
||
1494 | mov ecx, dword [forcedeth_txflags] |
||
1495 | or eax, ecx |
||
1496 | mov [ebx + forcedeth_TxDesc.FlagLen], eax |
||
1497 | |||
1498 | ; writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl); |
||
1499 | mov edi, dword [forcedeth_mapio_addr] |
||
1500 | mov eax, dword [forcedeth_desc_ver] |
||
1501 | or eax, NVREG_TXRXCTL_KICK |
||
1502 | mov dword [edi+NvRegTxRxControl], eax |
||
1503 | |||
1504 | ; pci_push(base); |
||
1505 | call forcedeth_pci_push |
||
1506 | |||
1507 | ; np->next_tx++ |
||
1508 | inc dword [forcedeth_next_tx] ; may be need to reset? Overflow? |
||
1509 | |||
1510 | ret |
||
1511 | |||
1512 | ;*************************************************************************** |
||
1513 | ; Function |
||
1514 | ; forcedeth_cable |
||
1515 | ; |
||
1516 | ; Description |
||
1517 | ; Return AL=0, if cable is not connected |
||
1518 | ; Returm AL=1, if cable is connected |
||
1519 | ; |
||
1520 | ;*************************************************************************** |
||
1521 | forcedeth_cable: |
||
1522 | |||
1523 | mov al, 1 |
||
1524 | cmp dword [forcedeth_nocable], 1 |
||
1525 | jne .return |
||
1526 | mov al, 0 |
||
1527 | |||
1528 | .return: |
||
1529 | ret |
||
1530 | |||
1531 | ;*************************************************************************** |
||
1532 | |||
1533 | |||
1534 | ; read/write a register on the PHY. |
||
1535 | ; Caller must guarantee serialization |
||
1536 | ; Input: EAX - miireg, EBX - addr, ECX - value |
||
1537 | ; Output: EAX - retval |
||
1538 | forcedeth_mii_rw: |
||
1539 | push ebx |
||
1540 | push eax ; save miireg |
||
1541 | ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus) |
||
1542 | mov edi, dword [forcedeth_mapio_addr] |
||
1543 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK |
||
1544 | |||
1545 | ; reg = readl(base + NvRegMIIControl) |
||
1546 | mov eax, dword [edi+NvRegMIIControl] |
||
1547 | test eax, NVREG_MIICTL_INUSE |
||
1548 | jz @f |
||
1549 | ; writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl) |
||
1550 | mov dword [edi+NvRegMIIControl], NVREG_MIICTL_INUSE |
||
1551 | ; nv_udelay(NV_MIIBUSY_DELAY) |
||
1552 | mov esi, NV_MIIBUSY_DELAY |
||
1553 | call forcedeth_nv_udelay |
||
1554 | @@: |
||
1555 | ; reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg |
||
1556 | pop edx ; restore miireg |
||
1557 | mov eax, ebx |
||
1558 | shl eax, NVREG_MIICTL_ADDRSHIFT |
||
1559 | or eax, edx |
||
1560 | mov dword [forcedeth_tmp_reg], eax |
||
1561 | |||
1562 | cmp ecx, MII_READ |
||
1563 | je @f |
||
1564 | ; writel(value, base + NvRegMIIData) |
||
1565 | mov dword [edi+NvRegMIIData], ecx |
||
1566 | ; reg |= NVREG_MIICTL_WRITE |
||
1567 | or dword [forcedeth_tmp_reg], NVREG_MIICTL_WRITE |
||
1568 | @@: |
||
1569 | ; writel(reg, base + NvRegMIIControl) |
||
1570 | mov eax, dword [forcedeth_tmp_reg] |
||
1571 | mov dword [edi+NvRegMIIControl], eax |
||
1572 | |||
1573 | push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
||
1574 | |||
1575 | ; reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL) |
||
1576 | stdcall forcedeth_reg_delay,NvRegMIIControl,NVREG_MIICTL_INUSE,0,NV_MIIPHY_DELAY,NV_MIIPHY_DELAYMAX,0 |
||
1577 | |||
1578 | pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
||
1579 | |||
1580 | test eax, eax |
||
1581 | jz @f |
||
1582 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d timed out.\n", edx, ebx |
||
1583 | mov eax, 0xffffffff |
||
1584 | jmp .return |
||
1585 | @@: |
||
1586 | cmp ecx, MII_READ |
||
1587 | je @f |
||
1588 | ;it was a write operation - fewer failures are detectable |
||
1589 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw wrote 0x%x to reg %d at PHY %d\n", ecx, edx, ebx |
||
1590 | mov eax, 0 |
||
1591 | jmp .return |
||
1592 | @@: |
||
1593 | ; readl(base + NvRegMIIStatus) |
||
1594 | mov eax, dword [edi+NvRegMIIStatus] |
||
1595 | test eax, NVREG_MIISTAT_ERROR |
||
1596 | jz @f |
||
1597 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d failed.\n", edx, ebx |
||
1598 | mov eax, 0xffffffff |
||
1599 | jmp .return |
||
1600 | @@: |
||
1601 | ; retval = readl(base + NvRegMIIData) |
||
1602 | mov eax, dword [edi+NvRegMIIData] |
||
1603 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw read from reg %d at PHY %d: 0x%x.\n", edx, ebx, eax |
||
1604 | .return: |
||
1605 | pop ebx |
||
1606 | ret |
||
1607 | |||
1608 | |||
1609 | |||
1610 | ; Input: ESI - delay |
||
1611 | ; Output: none |
||
1612 | forcedeth_nv_udelay: |
||
1613 | |||
1614 | push ebx |
||
1615 | cmp dword [forcedeth_in_shutdown], 0 |
||
1616 | jne @f |
||
1617 | call forcedeth_udelay ; delay on ESI |
||
1618 | jmp .return |
||
1619 | @@: |
||
1620 | |||
1621 | .loop: |
||
1622 | cmp esi, 0 |
||
1623 | je .return |
||
1624 | ; Don't allow an rx_ring overflow to happen |
||
1625 | ; while shutting down the NIC it will |
||
1626 | ; kill the receive function. |
||
1627 | |||
1628 | call forcedeth_drop_rx |
||
1629 | mov ebx, 3 ; sleep = 3 |
||
1630 | cmp ebx, esi ; if(sleep > delay) |
||
1631 | jle @f |
||
1632 | mov ebx, esi ; sleep = delay |
||
1633 | @@: |
||
1634 | push esi |
||
1635 | mov esi, ebx |
||
1636 | ; udelay(sleep) |
||
1637 | call forcedeth_udelay ; delay on ESI |
||
1638 | pop esi |
||
1639 | sub esi, ebx ; delay -= sleep |
||
1640 | jmp .loop |
||
1641 | |||
1642 | .return: |
||
1643 | pop ebx |
||
1644 | ret |
||
1645 | |||
1646 | |||
1647 | ; Input: none |
||
1648 | ; Output: none |
||
1649 | forcedeth_drop_rx: |
||
1650 | |||
1651 | push eax ebx ecx edi |
||
1652 | |||
1653 | ; events = readl(base + NvRegIrqStatus) |
||
1654 | mov edi, dword [forcedeth_mapio_addr] |
||
1655 | mov eax, dword [edi+NvRegIrqStatus] |
||
1656 | |||
1657 | test eax, eax |
||
1658 | jz @f |
||
1659 | ; writel(events, base + NvRegIrqStatus) |
||
1660 | mov dword [edi+NvRegIrqStatus], eax |
||
1661 | @@: |
||
1662 | ;if (!(events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF))) |
||
1663 | test eax, (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) |
||
1664 | jz .return |
||
1665 | |||
1666 | .loop: |
||
1667 | ; i = np->cur_rx % RX_RING |
||
1668 | mov eax, dword [forcedeth_cur_rx] |
||
1669 | and eax, (RX_RING-1) |
||
1670 | ; //Flags = le32_to_cpu(rx_ring[i].FlagLen) |
||
1671 | ; Flags = rx_ring[i].FlagLen |
||
1672 | mov cl, sizeof.forcedeth_RxDesc |
||
1673 | mul cl |
||
1674 | add eax, forcedeth_rx_ring |
||
1675 | mov ebx, eax |
||
1676 | mov eax, [ebx + forcedeth_RxDesc.FlagLen] |
||
1677 | ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) |
||
1678 | ; > len = Flags & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2) |
||
1679 | ; ??? len don't used later !!! ??? |
||
1680 | ; ... |
||
1681 | test eax, NV_RX_AVAIL |
||
1682 | jnz .return ; still owned by hardware, |
||
1683 | ; wmb() |
||
1684 | ; ??? may be empty function ??? |
||
1685 | ; np->cur_rx++ |
||
1686 | inc dword [forcedeth_cur_rx] |
||
1687 | ; alloc_rx(NULL) |
||
1688 | call forcedeth_alloc_rx |
||
1689 | .return: |
||
1690 | pop edi ecx ebx eax |
||
1691 | ret |
||
1692 | |||
1693 | |||
1694 | ; Fill rx ring entries. |
||
1695 | ; Return 1 if the allocations for the skbs failed and the |
||
1696 | ; rx engine is without Available descriptors |
||
1697 | ; Input: none |
||
1698 | ; Output: none |
||
1699 | forcedeth_alloc_rx: |
||
1700 | |||
1701 | push eax ebx ecx edx |
||
1702 | ; refill_rx = np->refill_rx |
||
1703 | mov ecx, dword [forcedeth_refill_rx] |
||
1704 | .loop: |
||
1705 | cmp dword [forcedeth_cur_rx], ecx |
||
1706 | je .loop_end |
||
1707 | ; nr = refill_rx % RX_RING |
||
1708 | mov eax, ecx |
||
1709 | and eax, (RX_RING-1) ; nr |
||
1710 | ; rx_ring[nr].PacketBuffer = &rxb[nr * RX_NIC_BUFSIZE] |
||
1711 | push ecx |
||
1712 | push eax |
||
1713 | mov cl, sizeof.forcedeth_RxDesc |
||
1714 | mul cl |
||
1715 | add eax, forcedeth_rx_ring |
||
1716 | mov ebx, eax |
||
1717 | pop eax |
||
1718 | mov cx, RX_NIC_BUFSIZE |
||
1719 | mul cx |
||
1720 | pop ecx |
||
1721 | add eax, forcedeth_rxb |
||
1722 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1723 | mov [ebx + forcedeth_RxDesc.PacketBuffer], eax |
||
1724 | ; wmb() |
||
1725 | ; ... |
||
1726 | ; rx_ring[nr].FlagLen = RX_NIC_BUFSIZE | NV_RX_AVAIL |
||
1727 | mov [ebx + forcedeth_RxDesc.FlagLen], (RX_NIC_BUFSIZE or NV_RX_AVAIL) |
||
1728 | inc ecx |
||
1729 | jmp .loop |
||
1730 | |||
1731 | .loop_end: |
||
1732 | ; np->refill_rx = refill_rx |
||
1733 | mov [forcedeth_refill_rx], ecx |
||
1734 | .return: |
||
1735 | pop edx ecx ebx eax |
||
1736 | ret |
||
1737 | |||
1738 | |||
1739 | ; Delay in millisec |
||
1740 | ; Input: ESI - delay in ms |
||
1741 | ; Output: none |
||
1742 | forcedeth_udelay: |
||
1743 | call delay_ms |
||
1744 | ret |
||
1745 | |||
1746 | ; Input: offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword |
||
1747 | ; Output: EAX - 0|1 |
||
1748 | ;;;;proc forcedeth_reg_delay,offset:word,mask:dword,target:dword,delay:word,delaymax:word,msg:dword |
||
1749 | proc forcedeth_reg_delay,offset:dword,mask:dword,target:dword,delay:dword,delaymax:dword,msg:dword |
||
1750 | |||
1751 | push ebx esi edi |
||
1752 | ; pci_push(base) |
||
1753 | call forcedeth_pci_push |
||
1754 | .loop: |
||
1755 | ; nv_udelay(delay) |
||
1756 | mov esi, dword [delay] |
||
1757 | call forcedeth_nv_udelay ; delay in esi |
||
1758 | mov eax, dword [delaymax] |
||
1759 | sub eax, dword [delay] |
||
1760 | mov dword [delaymax], eax |
||
1761 | ; if (delaymax < 0) |
||
1762 | test dword [delaymax], 0x80000000 |
||
1763 | jz @f |
||
1764 | ; return 1 |
||
1765 | mov eax, 1 |
||
1766 | jmp .return |
||
1767 | @@: |
||
1768 | ; while ((readl(base + offset) & mask) != target) |
||
1769 | mov edi, dword [forcedeth_mapio_addr] |
||
1770 | mov ebx, dword [offset] |
||
1771 | mov eax, dword [edi+ebx] |
||
1772 | and eax, dword [mask] |
||
1773 | cmp eax, dword [target] |
||
1774 | jne .loop |
||
1775 | xor eax, eax |
||
1776 | .return: |
||
1777 | pop edi esi ebx |
||
1778 | ret |
||
1779 | endp |
||
1780 | |||
1781 | |||
1782 | ; Input: none |
||
1783 | ; Output: none |
||
1784 | forcedeth_pci_push: |
||
1785 | push eax edi |
||
1786 | ;force out pending posted writes |
||
1787 | mov edi, dword [forcedeth_mapio_addr] |
||
1788 | mov eax, dword [edi] |
||
1789 | pop edi eax |
||
1790 | ret |
||
1791 | |||
1792 | |||
1793 | ; Input: none |
||
1794 | ; Output: EAX - result (0 = OK, other = error) |
||
1795 | forcedeth_phy_init: |
||
1796 | |||
1797 | push ebx ecx |
||
1798 | |||
1799 | ; set advertise register |
||
1800 | ; reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); |
||
1801 | ; EBX - addr, EAX - miireg, ECX - value |
||
1802 | mov ebx, dword [forcedeth_phyaddr] |
||
1803 | mov eax, MII_ADVERTISE |
||
1804 | mov ecx, MII_READ |
||
1805 | call forcedeth_mii_rw ; reg = eax |
||
1806 | |||
1807 | ; reg |= |
||
1808 | ; (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | |
||
1809 | ; ADVERTISE_100FULL | 0x800 | 0x400); |
||
1810 | or eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400) |
||
1811 | |||
1812 | ; if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg)) |
||
1813 | ; EBX - addr, EAX - miireg, ECX - value |
||
1814 | mov ecx, eax ; reg |
||
1815 | mov eax, MII_ADVERTISE |
||
1816 | call forcedeth_mii_rw ; eax -> return |
||
1817 | |||
1818 | test eax, eax |
||
1819 | jz @f |
||
1820 | ; printf("phy write to advertise failed.\n"); |
||
1821 | DEBUGF 1," K : FORCEDETH: phy write to advertise failed.\n" |
||
1822 | |||
1823 | ; return PHY_ERROR; |
||
1824 | mov eax, PHY_ERROR |
||
1825 | jmp .return |
||
1826 | @@: |
||
1827 | ; get phy interface type |
||
1828 | ; phyinterface = readl(base + NvRegPhyInterface); |
||
1829 | mov edi, dword [forcedeth_mapio_addr] |
||
1830 | mov eax, dword [edi+NvRegPhyInterface] ; phyinterface = eax |
||
1831 | mov dword [forcedeth_tmp_phyinterface], eax |
||
1832 | |||
1833 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1834 | DEBUGF 1," K : FORCEDETH: phy interface type = 0x%x\n", [forcedeth_tmp_phyinterface]:8 |
||
1835 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1836 | |||
1837 | ; see if gigabit phy |
||
1838 | ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); |
||
1839 | ; EBX - addr, EAX - miireg, ECX - value |
||
1840 | mov eax, MII_BMSR |
||
1841 | mov ecx, MII_READ |
||
1842 | call forcedeth_mii_rw ; mii_status = eax |
||
1843 | |||
1844 | ; if (mii_status & PHY_GIGABIT) |
||
1845 | test eax, PHY_GIGABIT |
||
1846 | jnz .gigabit |
||
1847 | ; np->gigabit = 0; |
||
1848 | mov dword [forcedeth_gigabit], 0 |
||
1849 | jmp .next_if |
||
1850 | |||
1851 | .gigabit: |
||
1852 | ; np->gigabit = PHY_GIGABIT; |
||
1853 | mov dword [forcedeth_gigabit], PHY_GIGABIT |
||
1854 | |||
1855 | ; mii_control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ); |
||
1856 | ; EBX - addr, EAX - miireg, ECX - value |
||
1857 | mov eax, MII_1000BT_CR |
||
1858 | mov ecx, MII_READ |
||
1859 | call forcedeth_mii_rw ; mii_control_1000 = eax |
||
1860 | |||
1861 | ; mii_control_1000 &= ~ADVERTISE_1000HALF; |
||
1862 | and eax, (not ADVERTISE_1000HALF) |
||
1863 | |||
1864 | ; if (phyinterface & PHY_RGMII) |
||
1865 | test dword [forcedeth_tmp_phyinterface], PHY_RGMII |
||
1866 | jz @f |
||
1867 | ; mii_control_1000 |= ADVERTISE_1000FULL |
||
1868 | or eax, ADVERTISE_1000FULL |
||
1869 | jmp .next |
||
1870 | @@: |
||
1871 | ; mii_control_1000 &= ~ADVERTISE_1000FULL |
||
1872 | and eax, (not ADVERTISE_1000FULL) |
||
1873 | |||
1874 | .next: |
||
1875 | ; if (mii_rw(nic, np->phyaddr, MII_1000BT_CR, mii_control_1000)) |
||
1876 | ; EBX - addr, EAX - miireg, ECX - value |
||
1877 | mov ecx, eax |
||
1878 | mov eax, MII_1000BT_CR |
||
1879 | call forcedeth_mii_rw ; eax -> return |
||
1880 | |||
1881 | test eax, eax |
||
1882 | jz .next_if |
||
1883 | |||
1884 | ; printf("phy init failed.\n"); |
||
1885 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1886 | |||
1887 | ; return PHY_ERROR; |
||
1888 | mov eax, PHY_ERROR |
||
1889 | jmp .return |
||
1890 | |||
1891 | .next_if: |
||
1892 | |||
1893 | ; reset the phy |
||
1894 | ; if (phy_reset(nic)) |
||
1895 | call forcedeth_phy_reset |
||
1896 | test eax, eax |
||
1897 | jz @f |
||
1898 | ; printf("phy reset failed\n") |
||
1899 | DEBUGF 1," K : FORCEDETH: phy reset failed.\n" |
||
1900 | ; return PHY_ERROR |
||
1901 | mov eax, PHY_ERROR |
||
1902 | jmp .return |
||
1903 | @@: |
||
1904 | |||
1905 | ; phy vendor specific configuration |
||
1906 | ; if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) |
||
1907 | cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA |
||
1908 | jne .next_if2 |
||
1909 | test dword [forcedeth_tmp_phyinterface], PHY_RGMII |
||
1910 | jz .next_if2 |
||
1911 | |||
1912 | ; phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ) |
||
1913 | ; EBX - addr, EAX - miireg, ECX - value |
||
1914 | mov eax, MII_RESV1 |
||
1915 | mov ecx, MII_READ |
||
1916 | call forcedeth_mii_rw ; phy_reserved = eax |
||
1917 | |||
1918 | ; phy_reserved &= ~(PHY_INIT1 | PHY_INIT2) |
||
1919 | and eax, (not (PHY_INIT1 or PHY_INIT2)) |
||
1920 | ; phy_reserved |= (PHY_INIT3 | PHY_INIT4) |
||
1921 | or eax, (PHY_INIT3 or PHY_INIT4) |
||
1922 | |||
1923 | ; if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved)) |
||
1924 | ; EBX - addr, EAX - miireg, ECX - value |
||
1925 | mov ecx, eax |
||
1926 | mov eax, MII_RESV1 |
||
1927 | call forcedeth_mii_rw ; eax -> return |
||
1928 | test eax, eax |
||
1929 | jz @f |
||
1930 | ; printf("phy init failed.\n") |
||
1931 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1932 | ; return PHY_ERROR |
||
1933 | mov eax, PHY_ERROR |
||
1934 | jmp .return |
||
1935 | @@: |
||
1936 | ; phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ); |
||
1937 | ; EBX - addr, EAX - miireg, ECX - value |
||
1938 | mov eax, MII_NCONFIG |
||
1939 | mov ecx, MII_READ |
||
1940 | call forcedeth_mii_rw ; phy_reserved = eax |
||
1941 | |||
1942 | ; phy_reserved |= PHY_INIT5 |
||
1943 | or eax, PHY_INIT5 |
||
1944 | |||
1945 | ; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved)) |
||
1946 | ; EBX - addr, EAX - miireg, ECX - value |
||
1947 | mov ecx, eax |
||
1948 | mov eax, MII_NCONFIG |
||
1949 | call forcedeth_mii_rw ; eax -> return |
||
1950 | test eax, eax |
||
1951 | jz .next_if2 |
||
1952 | ; printf("phy init failed.\n") |
||
1953 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1954 | ; return PHY_ERROR |
||
1955 | mov eax, PHY_ERROR |
||
1956 | jmp .return |
||
1957 | |||
1958 | .next_if2: |
||
1959 | |||
1960 | ; if (np->phy_oui == PHY_OUI_CICADA) |
||
1961 | cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA |
||
1962 | jne .restart |
||
1963 | |||
1964 | ; phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ) |
||
1965 | ; EBX - addr, EAX - miireg, ECX - value |
||
1966 | mov eax, MII_SREVISION |
||
1967 | mov ecx, MII_READ |
||
1968 | call forcedeth_mii_rw ; phy_reserved = eax |
||
1969 | |||
1970 | ; phy_reserved |= PHY_INIT6 |
||
1971 | or eax, PHY_INIT6 |
||
1972 | |||
1973 | ; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved)) |
||
1974 | mov ecx, eax |
||
1975 | mov eax, MII_SREVISION |
||
1976 | call forcedeth_mii_rw ; eax -> return |
||
1977 | test eax, eax |
||
1978 | jz .restart |
||
1979 | ; printf("phy init failed.\n"); |
||
1980 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1981 | ; return PHY_ERROR; |
||
1982 | jmp .return |
||
1983 | |||
1984 | .restart: |
||
1985 | ; restart auto negotiation |
||
1986 | ; mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ) |
||
1987 | ; EBX - addr, EAX - miireg, ECX - value |
||
1988 | mov eax, MII_BMCR |
||
1989 | mov ecx, MII_READ |
||
1990 | call forcedeth_mii_rw ; mii_control = eax |
||
1991 | |||
1992 | ; mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE) |
||
1993 | or eax, (BMCR_ANRESTART or BMCR_ANENABLE) |
||
1994 | |||
1995 | ; if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control)) |
||
1996 | mov ecx, eax |
||
1997 | mov eax, MII_BMCR |
||
1998 | call forcedeth_mii_rw ; eax -> return |
||
1999 | test eax, eax |
||
2000 | jz .ok |
||
2001 | |||
2002 | ; return PHY_ERROR; |
||
2003 | mov eax, PHY_ERROR |
||
2004 | jmp .return |
||
2005 | |||
2006 | .ok: |
||
2007 | mov eax, 0 |
||
2008 | .return: |
||
2009 | pop ecx ebx |
||
2010 | ret |
||
2011 | |||
2012 | |||
2013 | ; Input: none |
||
2014 | ; Output: EAX - result (0 = OK, other = error) |
||
2015 | forcedeth_phy_reset: |
||
2016 | |||
2017 | push ebx ecx edx |
||
2018 | |||
2019 | ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); |
||
2020 | ; EBX - addr, EAX - miireg, ECX - value |
||
2021 | mov ebx, dword [forcedeth_phyaddr] |
||
2022 | mov eax, MII_BMCR |
||
2023 | mov ecx, MII_READ |
||
2024 | call forcedeth_mii_rw ; miicontrol = eax |
||
2025 | |||
2026 | ; miicontrol |= BMCR_RESET; |
||
2027 | or eax, BMCR_RESET |
||
2028 | push eax |
||
2029 | |||
2030 | ; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol)) |
||
2031 | ; EBX - addr, EAX - miireg, ECX - value |
||
2032 | mov ecx, eax |
||
2033 | mov eax, MII_BMCR |
||
2034 | call forcedeth_mii_rw ; miicontrol = eax |
||
2035 | |||
2036 | test eax, eax |
||
2037 | jz @f |
||
2038 | pop eax |
||
2039 | mov eax, 0xffffffff |
||
2040 | jmp .return |
||
2041 | @@: |
||
2042 | pop eax |
||
2043 | |||
2044 | ; wait for 500ms |
||
2045 | ; mdelay(500) |
||
2046 | mov esi, 500 |
||
2047 | call forcedeth_udelay |
||
2048 | |||
2049 | ; must wait till reset is deasserted |
||
2050 | ; while (miicontrol & BMCR_RESET) { |
||
2051 | mov edx, 100 |
||
2052 | .while_loop: |
||
2053 | test eax, BMCR_RESET |
||
2054 | jz .while_loop_exit |
||
2055 | |||
2056 | ; mdelay(10); |
||
2057 | mov esi, 10 |
||
2058 | call forcedeth_udelay |
||
2059 | |||
2060 | ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); |
||
2061 | ; EBX - addr, EAX - miireg, ECX - value |
||
2062 | mov eax, MII_BMCR |
||
2063 | mov ecx, MII_READ |
||
2064 | call forcedeth_mii_rw ; miicontrol = eax |
||
2065 | |||
2066 | ; FIXME: 100 tries seem excessive |
||
2067 | ; if (tries++ > 100) |
||
2068 | dec edx |
||
2069 | jnz .while_loop |
||
2070 | ; return -1; |
||
2071 | mov eax, 0xffffffff |
||
2072 | jmp .return |
||
2073 | .while_loop_exit: |
||
2074 | ; return 0 |
||
2075 | mov eax, 0 |
||
2076 | .return: |
||
2077 | pop edx ecx ebx |
||
2078 | ret |
||
2079 | |||
2080 | ; Input: none |
||
2081 | ; Output: none |
||
2082 | forcedeth_mac_reset: |
||
2083 | push esi edi |
||
2084 | |||
2085 | ; dprintf("mac_reset\n") |
||
2086 | DEBUGF 1," K : FORCEDETH: mac_reset.\n" |
||
2087 | |||
2088 | ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) |
||
2089 | mov edi, dword [forcedeth_mapio_addr] |
||
2090 | mov eax, dword [forcedeth_desc_ver] |
||
2091 | or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) |
||
2092 | mov dword [edi+NvRegTxRxControl], eax |
||
2093 | |||
2094 | ; pci_push(base) |
||
2095 | call forcedeth_pci_push |
||
2096 | |||
2097 | ; writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset) |
||
2098 | mov dword [edi+NvRegMacReset], NVREG_MAC_RESET_ASSERT |
||
2099 | |||
2100 | ; pci_push(base) |
||
2101 | call forcedeth_pci_push |
||
2102 | |||
2103 | ; udelay(NV_MAC_RESET_DELAY) |
||
2104 | mov esi, NV_MAC_RESET_DELAY |
||
2105 | call forcedeth_nv_udelay |
||
2106 | |||
2107 | ; writel(0, base + NvRegMacReset) |
||
2108 | mov dword [edi+NvRegMacReset], 0 |
||
2109 | |||
2110 | ; pci_push(base) |
||
2111 | call forcedeth_pci_push |
||
2112 | |||
2113 | ; udelay(NV_MAC_RESET_DELAY) |
||
2114 | mov esi, NV_MAC_RESET_DELAY |
||
2115 | call forcedeth_nv_udelay |
||
2116 | |||
2117 | ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) |
||
2118 | mov eax, dword [forcedeth_desc_ver] |
||
2119 | or eax, NVREG_TXRXCTL_BIT2 |
||
2120 | mov dword [edi+NvRegTxRxControl], eax |
||
2121 | |||
2122 | ; pci_push(base) |
||
2123 | call forcedeth_pci_push |
||
2124 | |||
2125 | pop edi esi |
||
2126 | ret |
||
2127 | |||
2128 | ; Input: none |
||
2129 | ; Output: none |
||
2130 | forcedeth_init_ring: |
||
2131 | push eax ebx ecx |
||
2132 | |||
2133 | ; np->next_tx = np->nic_tx = 0 |
||
2134 | mov dword[forcedeth_next_tx], 0 |
||
2135 | mov dword[forcedeth_nic_tx], 0 |
||
2136 | |||
2137 | ; for (i = 0; i < TX_RING; i++) |
||
2138 | mov ecx, TX_RING |
||
2139 | |||
2140 | .for_loop: |
||
2141 | ; tx_ring[i].FlagLen = 0; |
||
2142 | mov eax, ecx |
||
2143 | dec eax |
||
2144 | mov bl, sizeof.forcedeth_TxDesc |
||
2145 | mul bl |
||
2146 | add eax, forcedeth_tx_ring |
||
2147 | mov ebx, eax |
||
2148 | mov dword [ebx + forcedeth_TxDesc.FlagLen], 0 |
||
2149 | loop .for_loop |
||
2150 | |||
2151 | ; np->cur_rx = RX_RING; |
||
2152 | mov dword [forcedeth_cur_rx], RX_RING |
||
2153 | ; np->refill_rx = 0; |
||
2154 | mov dword [forcedeth_refill_rx], 0 |
||
2155 | |||
2156 | ;for (i = 0; i < RX_RING; i++) |
||
2157 | mov ecx, RX_RING |
||
2158 | |||
2159 | .for_loop2: |
||
2160 | ; rx_ring[i].FlagLen = 0; |
||
2161 | mov eax, ecx |
||
2162 | dec eax |
||
2163 | mov bl, sizeof.forcedeth_RxDesc |
||
2164 | mul bl |
||
2165 | add eax, forcedeth_rx_ring |
||
2166 | mov ebx, eax |
||
2167 | mov dword [ebx + forcedeth_RxDesc.FlagLen], 0 |
||
2168 | loop .for_loop2 |
||
2169 | |||
2170 | ; alloc_rx(nic); |
||
2171 | call forcedeth_alloc_rx |
||
2172 | |||
2173 | .return: |
||
2174 | pop ecx ebx eax |
||
2175 | ret |
||
2176 | |||
2177 | ; Input: none |
||
2178 | ; Output: none |
||
2179 | forcedeth_txrx_reset: |
||
2180 | push eax esi edi |
||
2181 | |||
2182 | ; dprintf(("txrx_reset\n")) |
||
2183 | DEBUGF 1," K : FORCEDETH: txrx_reset.\n" |
||
2184 | |||
2185 | ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) |
||
2186 | mov edi, dword [forcedeth_mapio_addr] |
||
2187 | mov eax, dword [forcedeth_desc_ver] |
||
2188 | or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) |
||
2189 | mov dword [edi+NvRegTxRxControl], eax |
||
2190 | |||
2191 | ; pci_push(base) |
||
2192 | call forcedeth_pci_push |
||
2193 | |||
2194 | ; nv_udelay(NV_TXRX_RESET_DELAY) |
||
2195 | mov esi, NV_TXRX_RESET_DELAY |
||
2196 | call forcedeth_nv_udelay |
||
2197 | |||
2198 | ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) |
||
2199 | mov eax, dword [forcedeth_desc_ver] |
||
2200 | or eax, NVREG_TXRXCTL_BIT2 |
||
2201 | mov dword [edi+NvRegTxRxControl], eax |
||
2202 | |||
2203 | ; pci_push(base) |
||
2204 | call forcedeth_pci_push |
||
2205 | |||
2206 | .return: |
||
2207 | pop edi esi eax |
||
2208 | ret |
||
2209 | |||
2210 | ; Input: none |
||
2211 | ; Output: none |
||
2212 | forcedeth_set_multicast: |
||
2213 | push edi |
||
2214 | |||
2215 | ; u32 addr[2]; |
||
2216 | ; u32 mask[2]; |
||
2217 | ; u32 pff; |
||
2218 | ; u32 alwaysOff[2]; |
||
2219 | ; u32 alwaysOn[2]; |
||
2220 | ; |
||
2221 | ; memset(addr, 0, sizeof(addr)); |
||
2222 | ; memset(mask, 0, sizeof(mask)); |
||
2223 | ; |
||
2224 | ; pff = NVREG_PFF_MYADDR; |
||
2225 | ; |
||
2226 | ; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0; |
||
2227 | ; |
||
2228 | ; addr[0] = alwaysOn[0]; |
||
2229 | ; addr[1] = alwaysOn[1]; |
||
2230 | ; mask[0] = alwaysOn[0] | alwaysOff[0]; |
||
2231 | ; mask[1] = alwaysOn[1] | alwaysOff[1]; |
||
2232 | ; |
||
2233 | ; addr[0] |= NVREG_MCASTADDRA_FORCE; |
||
2234 | ; pff |= NVREG_PFF_ALWAYS; |
||
2235 | ; stop_rx(); |
||
2236 | call forcedeth_stop_rx |
||
2237 | ; writel(addr[0], base + NvRegMulticastAddrA); |
||
2238 | mov edi, dword [forcedeth_mapio_addr] |
||
2239 | mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
||
2240 | ; writel(addr[1], base + NvRegMulticastAddrB); |
||
2241 | mov dword [edi+NvRegMulticastAddrB], 0 |
||
2242 | ; writel(mask[0], base + NvRegMulticastMaskA); |
||
2243 | mov dword [edi+NvRegMulticastMaskA], 0 |
||
2244 | ; writel(mask[1], base + NvRegMulticastMaskB); |
||
2245 | mov dword [edi+NvRegMulticastMaskB], 0 |
||
2246 | ; writel(pff, base + NvRegPacketFilterFlags); |
||
2247 | mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_MYADDR or NVREG_PFF_ALWAYS) |
||
2248 | ; start_rx(nic); |
||
2249 | call forcedeth_start_rx |
||
2250 | |||
2251 | .return: |
||
2252 | pop edi |
||
2253 | ret |
||
2254 | |||
2255 | ; Input: none |
||
2256 | ; Output: none |
||
2257 | forcedeth_start_rx: |
||
2258 | push edi |
||
2259 | |||
2260 | ; dprintf(("start_rx\n")) |
||
2261 | DEBUGF 1," K : FORCEDETH: start_rx.\n" |
||
2262 | |||
2263 | ; Already running? Stop it. |
||
2264 | ; if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { |
||
2265 | mov edi, dword [forcedeth_mapio_addr] |
||
2266 | mov eax, dword [edi+NvRegReceiverControl] |
||
2267 | test eax, NVREG_RCVCTL_START |
||
2268 | jz @f |
||
2269 | ; writel(0, base + NvRegReceiverControl) |
||
2270 | mov dword [edi+NvRegReceiverControl], 0 |
||
2271 | ; pci_push(base) |
||
2272 | call forcedeth_pci_push |
||
2273 | |||
2274 | @@: |
||
2275 | |||
2276 | ; writel(np->linkspeed, base + NvRegLinkSpeed); |
||
2277 | mov eax, dword [forcedeth_linkspeed] |
||
2278 | mov dword [edi+NvRegLinkSpeed], eax |
||
2279 | ; pci_push(base); |
||
2280 | call forcedeth_pci_push |
||
2281 | ; writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); |
||
2282 | mov dword [edi+NvRegReceiverControl], NVREG_RCVCTL_START |
||
2283 | ; pci_push(base); |
||
2284 | call forcedeth_pci_push |
||
2285 | |||
2286 | .return: |
||
2287 | pop edi |
||
2288 | ret |
||
2289 | |||
2290 | ; Input: none |
||
2291 | ; Output: none |
||
2292 | forcedeth_stop_rx: |
||
2293 | push esi edi |
||
2294 | |||
2295 | ; dprintf(("stop_rx\n")) |
||
2296 | DEBUGF 1," K : FORCEDETH: stop_rx.\n" |
||
2297 | |||
2298 | ; writel(0, base + NvRegReceiverControl) |
||
2299 | mov edi, dword [forcedeth_mapio_addr] |
||
2300 | mov dword [edi+NvRegReceiverControl], 0 |
||
2301 | |||
2302 | push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
||
2303 | ; reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy"); |
||
2304 | stdcall forcedeth_reg_delay,NvRegReceiverStatus,NVREG_RCVSTAT_BUSY,0,NV_RXSTOP_DELAY1,NV_RXSTOP_DELAY1MAX,0 |
||
2305 | pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
||
2306 | |||
2307 | |||
2308 | ; nv_udelay(NV_RXSTOP_DELAY2) |
||
2309 | mov esi, NV_RXSTOP_DELAY2 |
||
2310 | call forcedeth_nv_udelay |
||
2311 | |||
2312 | ; writel(0, base + NvRegLinkSpeed) |
||
2313 | mov dword [edi+NvRegLinkSpeed], 0 |
||
2314 | |||
2315 | .return: |
||
2316 | pop edi esi |
||
2317 | ret |
||
2318 | |||
2319 | ; Input: none |
||
2320 | ; Output: EAX |
||
2321 | forcedeth_update_linkspeed: |
||
2322 | push ebx ecx esi edi |
||
2323 | |||
2324 | ; BMSR_LSTATUS is latched, read it twice: |
||
2325 | ; we want the current value. |
||
2326 | |||
2327 | ; mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) |
||
2328 | ;EBX - addr, EAX - miireg, ECX - value |
||
2329 | mov ebx, dword [forcedeth_phyaddr] |
||
2330 | mov eax, MII_BMSR |
||
2331 | mov ecx, MII_READ |
||
2332 | call forcedeth_mii_rw |
||
2333 | |||
2334 | |||
2335 | ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) |
||
2336 | ;EBX - addr, EAX - miireg, ECX - value |
||
2337 | mov ebx, dword [forcedeth_phyaddr] |
||
2338 | mov eax, MII_BMSR |
||
2339 | mov ecx, MII_READ |
||
2340 | call forcedeth_mii_rw ; mii_status = eax |
||
2341 | |||
2342 | ; yhlu |
||
2343 | |||
2344 | ; for(i=0;i<30;i++) { |
||
2345 | mov ecx, 30 |
||
2346 | .for_loop: |
||
2347 | push ecx |
||
2348 | |||
2349 | ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); |
||
2350 | ;EBX - addr, EAX - miireg, ECX - value |
||
2351 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2352 | mov eax, MII_BMSR |
||
2353 | mov ecx, MII_READ |
||
2354 | call forcedeth_mii_rw ; mii_status = eax |
||
2355 | |||
2356 | ; if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break; |
||
2357 | test eax, BMSR_LSTATUS |
||
2358 | jz @f |
||
2359 | test eax, BMSR_ANEGCOMPLETE |
||
2360 | jz @f |
||
2361 | ; break |
||
2362 | pop ecx |
||
2363 | jmp .break |
||
2364 | |||
2365 | @@: |
||
2366 | |||
2367 | ; mdelay(100); |
||
2368 | push eax ; ??? |
||
2369 | mov esi, 100 |
||
2370 | call forcedeth_udelay |
||
2371 | pop eax ; ??? |
||
2372 | |||
2373 | pop ecx |
||
2374 | loop .for_loop |
||
2375 | |||
2376 | .break: |
||
2377 | |||
2378 | ; if (!(mii_status & BMSR_LSTATUS)) { |
||
2379 | test eax, BMSR_LSTATUS |
||
2380 | jnz @f |
||
2381 | |||
2382 | ; printf("no link detected by phy - falling back to 10HD.\n") |
||
2383 | DEBUGF 1," K : FORCEDETH: update_linkspeed: no link detected by phy - falling back to 10HD.\n" |
||
2384 | |||
2385 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2386 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2387 | |||
2388 | ; newdup = 0; |
||
2389 | mov dword [forcedeth_tmp_newdup], 0 |
||
2390 | ; retval = 0; |
||
2391 | mov dword [forcedeth_tmp_retval], 0 |
||
2392 | |||
2393 | ; goto set_speed; |
||
2394 | jmp .set_speed |
||
2395 | |||
2396 | @@: |
||
2397 | |||
2398 | ; check auto negotiation is complete |
||
2399 | ; if (!(mii_status & BMSR_ANEGCOMPLETE)) { |
||
2400 | test eax, BMSR_ANEGCOMPLETE |
||
2401 | jnz @f |
||
2402 | |||
2403 | ; still in autonegotiation - configure nic for 10 MBit HD and wait. |
||
2404 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2405 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2406 | |||
2407 | ; newdup = 0 |
||
2408 | mov dword [forcedeth_tmp_newdup], 0 |
||
2409 | |||
2410 | ; retval = 0 |
||
2411 | mov dword [forcedeth_tmp_retval], 0 |
||
2412 | |||
2413 | ; printf("autoneg not completed - falling back to 10HD.\n") |
||
2414 | DEBUGF 1," K : FORCEDETH: update_linkspeed: autoneg not completed - falling back to 10HD.\n" |
||
2415 | |||
2416 | ; goto set_speed |
||
2417 | jmp .set_speed |
||
2418 | |||
2419 | @@: |
||
2420 | |||
2421 | ; retval = 1 |
||
2422 | mov dword [forcedeth_tmp_retval], 1 |
||
2423 | |||
2424 | ; if (np->gigabit == PHY_GIGABIT) { |
||
2425 | cmp dword [forcedeth_gigabit], PHY_GIGABIT |
||
2426 | jne .end_if |
||
2427 | ; control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ) |
||
2428 | ;EBX - addr, EAX - miireg, ECX - value |
||
2429 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2430 | mov eax, MII_1000BT_CR |
||
2431 | mov ecx, MII_READ |
||
2432 | call forcedeth_mii_rw ; control_1000 = eax |
||
2433 | mov dword [forcedeth_tmp_control_1000], eax |
||
2434 | |||
2435 | ; status_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_SR, MII_READ) |
||
2436 | ;EBX - addr, EAX - miireg, ECX - value |
||
2437 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2438 | mov eax, MII_1000BT_SR |
||
2439 | mov ecx, MII_READ |
||
2440 | call forcedeth_mii_rw ; status_1000 = eax |
||
2441 | ;mov dword [forcedeth_tmp_status_1000], eax |
||
2442 | |||
2443 | ; if ((control_1000 & ADVERTISE_1000FULL) && |
||
2444 | ; (status_1000 & LPA_1000FULL)) { |
||
2445 | test eax, LPA_1000FULL |
||
2446 | jz .end_if |
||
2447 | test dword [forcedeth_tmp_control_1000], ADVERTISE_1000FULL |
||
2448 | jz .end_if |
||
2449 | |||
2450 | ; printf ("update_linkspeed: GBit ethernet detected.\n") |
||
2451 | DEBUGF 1," K : FORCEDETH: update_linkspeed: GBit ethernet detected.\n" |
||
2452 | |||
2453 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000 |
||
2454 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_1000) |
||
2455 | |||
2456 | ; newdup = 1 |
||
2457 | mov dword [forcedeth_tmp_newdup], 1 |
||
2458 | |||
2459 | ; goto set_speed |
||
2460 | jmp .set_speed |
||
2461 | |||
2462 | .end_if: |
||
2463 | |||
2464 | ; adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); |
||
2465 | ;EBX - addr, EAX - miireg, ECX - value |
||
2466 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2467 | mov eax, MII_ADVERTISE |
||
2468 | mov ecx, MII_READ |
||
2469 | call forcedeth_mii_rw ; adv = eax |
||
2470 | mov dword [forcedeth_tmp_adv], eax |
||
2471 | |||
2472 | ; lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ); |
||
2473 | ;EBX - addr, EAX - miireg, ECX - value |
||
2474 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2475 | mov eax, MII_LPA |
||
2476 | mov ecx, MII_READ |
||
2477 | call forcedeth_mii_rw ; lpa = eax |
||
2478 | mov dword [forcedeth_tmp_lpa], eax |
||
2479 | |||
2480 | ; dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa)); |
||
2481 | DEBUGF 1," K : FORCEDETH: update_linkspeed: PHY advertises 0x%x, lpa 0x%x.\n", [forcedeth_tmp_adv]:8, [forcedeth_tmp_lpa]:8 |
||
2482 | |||
2483 | ; FIXME: handle parallel detection properly, handle gigabit ethernet |
||
2484 | ; lpa = lpa & adv |
||
2485 | mov eax, dword [forcedeth_tmp_adv] |
||
2486 | and dword [forcedeth_tmp_lpa], eax |
||
2487 | |||
2488 | mov eax, dword [forcedeth_tmp_lpa] |
||
2489 | |||
2490 | ; if (lpa & LPA_100FULL) { |
||
2491 | test eax, LPA_100FULL |
||
2492 | jz @f |
||
2493 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 |
||
2494 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) |
||
2495 | ; newdup = 1 |
||
2496 | mov dword [forcedeth_tmp_newdup], 1 |
||
2497 | jmp .set_speed |
||
2498 | @@: |
||
2499 | ; } else if (lpa & LPA_100HALF) { |
||
2500 | test eax, LPA_100HALF |
||
2501 | jz @f |
||
2502 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 |
||
2503 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) |
||
2504 | ; newdup = 0 |
||
2505 | mov dword [forcedeth_tmp_newdup], 0 |
||
2506 | jmp .set_speed |
||
2507 | @@: |
||
2508 | ; } else if (lpa & LPA_10FULL) { |
||
2509 | test eax, LPA_10FULL |
||
2510 | jz @f |
||
2511 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2512 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2513 | ; newdup = 1 |
||
2514 | mov dword [forcedeth_tmp_newdup], 1 |
||
2515 | jmp .set_speed |
||
2516 | @@: |
||
2517 | ; } else if (lpa & LPA_10HALF) { |
||
2518 | test eax, LPA_10HALF |
||
2519 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; |
||
2520 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2521 | ; newdup = 0; |
||
2522 | mov dword [forcedeth_tmp_newdup], 0 |
||
2523 | jmp .set_speed |
||
2524 | @@: |
||
2525 | ; } else { |
||
2526 | ; printf("bad ability %hX - falling back to 10HD.\n", lpa) |
||
2527 | DEBUGF 1," K : FORCEDETH: update_linkspeed: bad ability 0x%x - falling back to 10HD.\n", eax |
||
2528 | |||
2529 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2530 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2531 | ; newdup = 0 |
||
2532 | mov dword [forcedeth_tmp_newdup], 0 |
||
2533 | ; } |
||
2534 | |||
2535 | .set_speed: |
||
2536 | |||
2537 | ; if (np->duplex == newdup && np->linkspeed == newls) |
||
2538 | mov eax, dword [forcedeth_tmp_newdup] |
||
2539 | cmp eax, dword [forcedeth_duplex] |
||
2540 | jne .end_if2 |
||
2541 | mov eax, dword [forcedeth_tmp_newls] |
||
2542 | cmp eax, dword [forcedeth_linkspeed] |
||
2543 | jne .end_if2 |
||
2544 | ; return retval; |
||
2545 | jmp .return |
||
2546 | |||
2547 | .end_if2: |
||
2548 | |||
2549 | ; dprintf(("changing link setting from %d/%s to %d/%s.\n", |
||
2550 | ; np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex")) |
||
2551 | DEBUGF 1," K : FORCEDETH: update_linkspeed: changing link from %x/XD to %x/XD.\n", [forcedeth_linkspeed]:8, [forcedeth_tmp_newls]:8 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||
2552 | |||
2553 | ; np->duplex = newdup |
||
2554 | mov eax, dword [forcedeth_tmp_newdup] |
||
2555 | mov dword [forcedeth_duplex], eax |
||
2556 | |||
2557 | ; np->linkspeed = newls |
||
2558 | mov eax, [forcedeth_tmp_newls] |
||
2559 | mov dword [forcedeth_linkspeed], eax |
||
2560 | |||
2561 | ; if (np->gigabit == PHY_GIGABIT) { |
||
2562 | cmp dword [forcedeth_gigabit], PHY_GIGABIT |
||
2563 | jne .end_if3 |
||
2564 | |||
2565 | ; phyreg = readl(base + NvRegRandomSeed); |
||
2566 | mov edi, dword [forcedeth_mapio_addr] |
||
2567 | mov eax, dword [edi+NvRegRandomSeed] |
||
2568 | |||
2569 | ; phyreg &= ~(0x3FF00); |
||
2570 | and eax, not (0x3FF00) |
||
2571 | mov ecx, eax ; phyreg = ecx |
||
2572 | |||
2573 | ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) |
||
2574 | mov eax, dword [forcedeth_linkspeed] |
||
2575 | and eax, 0xFFF |
||
2576 | cmp eax, NVREG_LINKSPEED_10 |
||
2577 | jne @f |
||
2578 | ; phyreg |= NVREG_RNDSEED_FORCE3 |
||
2579 | or ecx, NVREG_RNDSEED_FORCE3 |
||
2580 | jmp .end_if4 |
||
2581 | @@: |
||
2582 | ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
||
2583 | cmp eax, NVREG_LINKSPEED_100 |
||
2584 | jne @f |
||
2585 | ; phyreg |= NVREG_RNDSEED_FORCE2 |
||
2586 | or ecx, NVREG_RNDSEED_FORCE2 |
||
2587 | jmp .end_if4 |
||
2588 | @@: |
||
2589 | ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
||
2590 | cmp eax, NVREG_LINKSPEED_1000 |
||
2591 | jne .end_if4 |
||
2592 | ; phyreg |= NVREG_RNDSEED_FORCE |
||
2593 | or ecx, NVREG_RNDSEED_FORCE |
||
2594 | .end_if4: |
||
2595 | ; writel(phyreg, base + NvRegRandomSeed) |
||
2596 | mov dword [edi+NvRegRandomSeed], ecx |
||
2597 | |||
2598 | .end_if3: |
||
2599 | |||
2600 | ; phyreg = readl(base + NvRegPhyInterface) |
||
2601 | mov ecx, dword [edi+NvRegPhyInterface] |
||
2602 | |||
2603 | ; phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000) |
||
2604 | and ecx, not (PHY_HALF or PHY_100 or PHY_1000) |
||
2605 | |||
2606 | ; if (np->duplex == 0) |
||
2607 | cmp dword [forcedeth_duplex], 0 |
||
2608 | jne @f |
||
2609 | ; phyreg |= PHY_HALF |
||
2610 | or ecx, PHY_HALF |
||
2611 | @@: |
||
2612 | ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
||
2613 | mov eax, dword [forcedeth_linkspeed] |
||
2614 | and eax, 0xFFF |
||
2615 | cmp eax, NVREG_LINKSPEED_100 |
||
2616 | jne @f |
||
2617 | ; phyreg |= PHY_100 |
||
2618 | or ecx, PHY_100 |
||
2619 | jmp .end_if5 |
||
2620 | @@: |
||
2621 | ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
||
2622 | cmp eax, NVREG_LINKSPEED_1000 |
||
2623 | jne .end_if5 |
||
2624 | ; phyreg |= PHY_1000 |
||
2625 | or ecx, PHY_1000 |
||
2626 | |||
2627 | .end_if5: |
||
2628 | |||
2629 | ; writel(phyreg, base + NvRegPhyInterface) |
||
2630 | mov dword [edi+NvRegPhyInterface], ecx |
||
2631 | |||
2632 | ; writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); |
||
2633 | cmp dword [forcedeth_duplex], 0 |
||
2634 | je @f |
||
2635 | mov ecx, 0 |
||
2636 | jmp .next |
||
2637 | @@: |
||
2638 | mov ecx, NVREG_MISC1_HD |
||
2639 | .next: |
||
2640 | or ecx, NVREG_MISC1_FORCE |
||
2641 | mov dword [edi+NvRegMisc1], ecx |
||
2642 | |||
2643 | ; pci_push(base) |
||
2644 | call forcedeth_pci_push |
||
2645 | |||
2646 | ; writel(np->linkspeed, base + NvRegLinkSpeed) |
||
2647 | mov eax, dword [forcedeth_linkspeed] |
||
2648 | mov dword [edi+NvRegLinkSpeed], eax |
||
2649 | |||
2650 | ; pci_push(base) |
||
2651 | call forcedeth_pci_push |
||
2652 | |||
2653 | .return: |
||
2654 | ; return retval |
||
2655 | mov eax, dword [forcedeth_tmp_retval] |
||
2656 | pop edi esi ecx ebx |
||
2657 | ret |
||
2658 | |||
2659 | |||
2660 | ; Input: none |
||
2661 | ; Output: none |
||
2662 | forcedeth_start_tx: |
||
2663 | push edi |
||
2664 | ; dprintf(("start_tx\n")) |
||
2665 | DEBUGF 1," K : FORCEDETH: start_tx.\n" |
||
2666 | |||
2667 | ; writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl) |
||
2668 | mov edi, dword [forcedeth_mapio_addr] |
||
2669 | mov dword [edi+NvRegTransmitterControl], NVREG_XMITCTL_START |
||
2670 | |||
2671 | ; pci_push(base) |
||
2672 | call forcedeth_pci_push |
||
2673 | |||
2674 | .return: |
||
2675 | pop edi |
||
2676 | ret |
||
2677 | |||
2678 | ; Interrupt handler |
||
2679 | forcedeth_int_handler: |
||
2680 | DEBUGF 1," K : FORCEDETH: interrupt handler.\n" |
||
2681 | |||
2682 | ret30;i++)>>>>><>>><>>>=>><>><>><> |
||
2683 |