Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
261 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                    ;;
1237 clevermous 3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.       ;;
431 serge 4
;; Distributed under terms of the GNU General Public License          ;;
5
;;                                                                    ;;
1237 clevermous 6
;;  Ethernet driver for KolibriOS                                     ;;
7
;;  This is an adaptation of MenuetOS driver with minimal changes.    ;;
8
;;  Changes were made by CleverMouse. Original copyright follows.     ;;
261 hidnplayr 9
;;                                                                    ;;
10
;;  This driver is based on the SIS900 driver from                    ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is           ;;
12
;;                                                                    ;;
13
;;          GNU GENERAL PUBLIC LICENSE                                ;;
14
;;             Version 2, June 1991                                   ;;
15
;;                                                                    ;;
16
;;  remaining parts Copyright 2004 Jason Delozier,                    ;;
17
;;   cordata51@hotmail.com                                            ;;
18
;;                                                                    ;;
19
;;  See file COPYING for details                                      ;;
20
;;                                                                    ;;
21
;;  Updates:                                                          ;;
22
;;    Revision Look up table and SIS635 Mac Address by Jarek Pelczar  ;;
23
;;                                                                    ;;
24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
593 mikedld 25
 
1237 clevermous 26
; $Revision: 1377 $
593 mikedld 27
 
1237 clevermous 28
format MS COFF
593 mikedld 29
 
1237 clevermous 30
	API_VERSION		equ 0x01000100
31
 
32
	DEBUG			equ 1
33
	__DEBUG__		equ 1
34
	__DEBUG_LEVEL__ 	equ 1
35
 
36
include 'proc32.inc'
37
include 'imports.inc'
38
include 'fdo.inc'
39
 
40
public START
41
public version
42
 
43
struc IOCTL {
44
      .handle		dd ?
45
      .io_code		dd ?
46
      .input		dd ?
47
      .inp_size 	dd ?
48
      .output		dd ?
49
      .out_size 	dd ?
50
}
51
 
52
virtual at 0
53
  IOCTL IOCTL
54
end virtual
55
 
1254 hidnplayr 56
NUM_RX_DESC    equ    4 	      ;* Number of RX descriptors *
57
NUM_TX_DESC    equ    1 	      ;* Number of TX descriptors *
58
RX_BUFF_SZ	    equ    1520 	   ;* Buffer size for each Rx buffer *
59
TX_BUFF_SZ	    equ    1516 	   ;* Buffer size for each Tx buffer *
1237 clevermous 60
MAX_ETH_FRAME_SIZE  equ    1516
61
 
62
TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ
63
 
64
struc ETH_DEVICE {
65
; pointers to procedures
66
      .unload		dd ?
67
      .reset		dd ?
68
      .transmit 	dd ?
69
      .set_MAC		dd ?
70
      .get_MAC		dd ?
71
      .set_mode 	dd ?
72
      .get_mode 	dd ?
73
; status & variables
74
      .bytes_tx 	dq ?
75
      .bytes_rx 	dq ?
76
      .packets_tx	dd ?
77
      .packets_rx	dd ?
78
      .mode		dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
79
      .name		dd ?
80
      .mac		dp ?
81
; device specific
82
      .io_addr		dd ?
83
      .pci_bus		db ?
84
      .pci_dev		db ?
85
      .irq_line 	db ?
86
      .cur_rx		db ?
1254 hidnplayr 87
      .pci_revision	db ?
88
      .table_entries:	db ?
1237 clevermous 89
align 4
1254 hidnplayr 90
      .special_func:	dd 0
1237 clevermous 91
      .txd: times (3 * NUM_TX_DESC) dd 0
92
      .rxd: times (3 * NUM_RX_DESC) dd 0
93
      .size:
94
}
95
 
96
; First page is designated to ETH_DEVICE, buffers start from second
97
ALLOCATION_SIZE = ((device.size+0FFFh) and not 0FFFh) + TOTAL_BUFFERS_SIZE
98
; Note that buffers must be contiguous in the physical memory;
99
; because KernelAlloc allocates contiguous physical pages only in 8-pages blocks,
100
; align ALLOCATION_SIZE up to 8*(page size) = 8000h
101
ALLOCATION_SIZE = (ALLOCATION_SIZE + 7FFFh) and not 7FFFh
102
 
103
MAX_DEVICES = 16	; maximum number of devices which this driver can handle
104
 
105
virtual at 0
106
  device ETH_DEVICE
107
end virtual
108
 
109
	PCI_HEADER_TYPE 	      equ 0x0e	;8 bit
110
	PCI_BASE_ADDRESS_0	      equ 0x10	;32 bit
111
	PCI_BASE_ADDRESS_5	      equ 0x24	;32 bits
112
	PCI_BASE_ADDRESS_SPACE_IO     equ 0x01
113
	PCI_VENDOR_ID		      equ 0x00	;16 bit
114
	PCI_BASE_ADDRESS_IO_MASK      equ 0xFFFFFFFC
115
 
116
section '.flat' code readable align 16
117
 
118
; Driver entry point - register our service when the driver is loading.
119
; TODO: add needed operations when unloading
120
START:
121
	cmp	dword [esp+4], 1
122
	jne	.exit
1254 hidnplayr 123
	stdcall RegService, my_service, service_proc
1237 clevermous 124
	ret	4
125
.exit:
126
	xor	eax, eax
127
	ret	4
128
 
129
; Service procedure for the driver - handle all I/O requests for the driver.
130
; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
131
service_proc:
132
; 1. Get parameter from the stack: [esp+4] is the first parameter,
1254 hidnplayr 133
;       pointer to IOCTL structure.
1237 clevermous 134
	mov	edx, [esp+4]	; edx -> IOCTL
135
; 2. Get request code and select a handler for the code.
1377 clevermous 136
	mov	eax, [edx+IOCTL.io_code]
1237 clevermous 137
	test	eax, eax	; check for SRV_GETVERSION
138
	jnz	@f
139
; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION.
140
; 3a. Output size must be at least 4 bytes.
141
	cmp	[edx+IOCTL.out_size], 4
142
	jl	.fail
143
; 3b. Write result to the output buffer.
144
	mov	eax, [edx+IOCTL.output]
145
	mov	[eax], dword API_VERSION
146
; 3c. Return success.
147
	xor	eax, eax
148
	ret	4
149
@@:
150
	dec	eax	; check for SRV_HOOK
151
	jnz	.fail
152
; 4. This is SRV_HOOK request, input defines the device to hook, no output.
153
; 4a. The driver works only with PCI devices,
1254 hidnplayr 154
;       so input must be at least 3 bytes long.
1237 clevermous 155
	cmp	[edx + IOCTL.inp_size], 3
156
	jl	.fail
157
; 4b. First byte of input is bus type, 1 stands for PCI.
158
	mov	eax, [edx + IOCTL.input]
159
	cmp	byte [eax], 1
160
	jne	.fail
161
; 4c. Second and third bytes of the input define the device: bus and dev.
1254 hidnplayr 162
;       Word in bx holds both bytes.
1237 clevermous 163
	mov	bx, [eax+1]
164
; 4d. Check if the device was already hooked,
1254 hidnplayr 165
;       scan through the list of known devices.
1237 clevermous 166
	mov	esi, DEV_LIST
167
	mov	ecx, [NUM_DEV]
168
	test	ecx, ecx
169
	jz	.firstdevice
170
  .nextdevice:
171
	lodsd
172
	cmp	bx, word [eax + device.pci_bus]
173
	je	.find_devicenum
174
	loop	.nextdevice
175
; 4e. This device doesn't have its own eth_device structure yet, let's create one
176
  .firstdevice:
177
; 4f. Check that we have place for new device.
178
	cmp	[NUM_DEV], MAX_DEVICES
179
	jge	.fail
180
; 4g. Allocate memory for device descriptor and receive+transmit buffers.
181
	stdcall KernelAlloc, ALLOCATION_SIZE
182
	test	eax, eax
183
	jz	.fail
184
; 4h. Zero the structure.
185
	push	eax
186
	mov	edi, eax
187
	mov	ecx, (device.size + 3) shr 2
188
	xor	eax, eax
189
	rep	stosd
190
	pop	eax
191
; 4i. Save PCI coordinates, loaded to bx at 4c.
192
	mov	word [eax+device.pci_bus], bx
193
	mov	ebx, eax				; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
194
; 4j. Fill in the direct call addresses into the struct.
195
; Note that get_MAC pointer is filled in initialization by SIS900_probe.
196
	mov	dword [ebx+device.reset], sis900_init
197
	mov	dword [ebx+device.transmit], transmit
1254 hidnplayr 198
;       mov     dword [ebx+device.get_MAC], read_mac
1237 clevermous 199
	mov	dword [ebx+device.set_MAC], write_mac
200
	mov	dword [ebx+device.unload], unload
201
	mov	dword [ebx+device.name], my_service
202
 
203
; 4k. Now, it's time to find the base io addres of the PCI device
204
; TODO: implement check if bus and dev exist on this machine
205
 
206
	mov	edx, PCI_BASE_ADDRESS_0
207
.reg_check:
208
	push	edx
1254 hidnplayr 209
	stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], edx
1237 clevermous 210
	pop	edx
211
	test	al, PCI_BASE_ADDRESS_SPACE_IO
212
	jz	.inc_reg
213
	and	eax, PCI_BASE_ADDRESS_IO_MASK
214
	jnz	.got_io
215
 
216
  .inc_reg:
217
	add	edx, 4
218
	cmp	edx, PCI_BASE_ADDRESS_5
219
	jbe	.reg_check
220
	jmp	.fail
221
 
222
  .got_io:
223
	mov	[ebx+device.io_addr], eax
224
 
225
; 4l. We've found the io address, find IRQ now
1254 hidnplayr 226
	stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x3c
1237 clevermous 227
	mov	byte [ebx+device.irq_line], al
228
 
229
; 4m. Add new device to the list (required for int_handler).
230
	mov	eax, [NUM_DEV]
231
	mov	[DEV_LIST+4*eax], ebx
232
	inc	[NUM_DEV]
233
 
234
; 4m. Ok, the eth_device structure is ready, let's probe the device
235
 
236
	call	SIS900_probe
237
	test	eax, eax
238
	jnz	.destroy
239
; 4n. If device was successfully initialized, register it for the kernel.
240
 
241
	call	EthRegDev
242
	cmp	eax, -1
243
	je	.destroy
244
 
245
	ret	4
246
 
247
; 5. If the device was already loaded, find the device number and return it in eax
248
 
249
  .find_devicenum:
250
	mov	ebx, eax
251
	call	EthStruc2Dev						; This kernel procedure converts a pointer to device struct in ebx
252
									; into a device number in edi
253
	mov	eax, edi						; Application wants it in eax instead
254
	ret	4
255
 
256
; If an error occured, remove all allocated data and exit (returning -1 in eax)
257
 
258
  .destroy:
259
	dec	[NUM_DEV]
260
	; todo: reset device into virgin state
261
 
262
  .err:
263
	stdcall KernelFree, ebx
264
 
265
 
266
  .fail:
267
	xor	eax, eax
268
	ret	4
269
 
270
 
271
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
272
;;                                                                        ;;
273
;;        Actual Hardware dependent code starts here                      ;;
274
;;                                                                        ;;
275
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
276
 
277
unload:
278
	; TODO: (in this particular order)
279
	;
280
	; - Stop the device
281
	; - Detach int handler
282
	; - Remove device from local list
283
	; - call unregister function in kernel
284
	; - Remove all allocated structures and buffers the card used
285
 
286
	or	eax,-1
287
 
288
ret
289
 
261 hidnplayr 290
;********************************************************************
291
;   Interface
292
;      SIS900_reset
293
;      SIS900_probe
294
;      SIS900_poll
295
;      SIS900_transmit
296
;
297
;********************************************************************
298
;********************************************************************
299
;  Comments:
300
;    Known to work with the following SIS900 ethernet cards:
301
;      -  Device ID: 0x0900   Vendor ID: 0x1039   Revision: 0x91
302
;      -  Device ID: 0x0900   Vendor ID: 0x1039   Revision: 0x90
303
;
304
;    If your card is not listed, try it and let me know if it
305
;    functions properly and it will be aded to the list.  If not
306
;    we may be able to add support for it.
307
;
308
;  ToDo:
309
;     -  Enable MII interface for reading speed
310
;        and duplex settings.
311
;
312
;     -  Update Poll routine to support packet fragmentation.
313
;
314
;     -  Add additional support for other sis900 based cards
315
;
316
;********************************************************************
317
 
318
; comment the next line out if you don't want debug info printed
319
; on the debug board. This option adds a lot of bytes to the driver
320
; so it's worth to comment it out.
321
;        SIS900_DEBUG equ 1
322
 
1254 hidnplayr 323
SIS900_ETH_ALEN equ	6	;* Size of Ethernet address *
324
SIS900_ETH_HLEN equ	14	;* Size of ethernet header *
325
SIS900_ETH_ZLEN equ	60	;* Minimum packet length *
261 hidnplayr 326
SIS900_DSIZE equ 0x00000fff
327
SIS900_CRC_SIZE equ 4
328
SIS900_RFADDR_shift equ 16
329
;SIS900 Symbolic offsets to registers.
1254 hidnplayr 330
    SIS900_cr		equ	0x0		  ; Command Register
331
    SIS900_cfg		equ	0x4	  ; Configuration Register
261 hidnplayr 332
    SIS900_mear     equ     0x8       ; EEPROM Access Register
333
    SIS900_ptscr    equ     0xc       ; PCI Test Control Register
1254 hidnplayr 334
    SIS900_isr		equ	0x10	  ; Interrupt Status Register
335
    SIS900_imr		equ	0x14	  ; Interrupt Mask Register
336
    SIS900_ier		equ	0x18	  ; Interrupt Enable Register
337
    SIS900_epar 	equ	0x18	  ; Enhanced PHY Access Register
261 hidnplayr 338
    SIS900_txdp     equ     0x20      ; Transmit Descriptor Pointer Register
339
    SIS900_txcfg    equ     0x24      ; Transmit Configuration Register
340
    SIS900_rxdp     equ     0x30      ; Receive Descriptor Pointer Register
341
    SIS900_rxcfg    equ     0x34      ; Receive Configuration Register
342
    SIS900_flctrl   equ     0x38      ; Flow Control Register
343
    SIS900_rxlen    equ     0x3c      ; Receive Packet Length Register
344
    SIS900_rfcr     equ     0x48      ; Receive Filter Control Register
345
    SIS900_rfdr     equ     0x4C      ; Receive Filter Data Register
346
    SIS900_pmctrl   equ     0xB0      ; Power Management Control Register
1254 hidnplayr 347
    SIS900_pmer 	equ	0xB4	  ; Power Management Wake-up Event Register
261 hidnplayr 348
;SIS900 Command Register Bits
1254 hidnplayr 349
    SIS900_RELOAD	equ	 0x00000400
350
    SIS900_ACCESSMODE	equ	 0x00000200
351
    SIS900_RESET	equ	 0x00000100
352
    SIS900_SWI		equ	 0x00000080
353
    SIS900_RxRESET	equ	 0x00000020
354
    SIS900_TxRESET	equ	 0x00000010
355
    SIS900_RxDIS	equ	 0x00000008
356
    SIS900_RxENA	equ	 0x00000004
357
    SIS900_TxDIS	equ	 0x00000002
358
    SIS900_TxENA	equ	 0x00000001
261 hidnplayr 359
;SIS900 Configuration Register Bits
1254 hidnplayr 360
    SIS900_DESCRFMT	 equ	0x00000100 ; 7016 specific
361
    SIS900_REQALG	 equ	0x00000080
362
    SIS900_SB		 equ	0x00000040
363
    SIS900_POW		 equ	0x00000020
364
    SIS900_EXD		 equ	0x00000010
365
    SIS900_PESEL	 equ	0x00000008
366
    SIS900_LPM		 equ	0x00000004
367
    SIS900_BEM		 equ	0x00000001
368
    SIS900_RND_CNT	 equ	0x00000400
369
    SIS900_FAIR_BACKOFF  equ	0x00000200
370
    SIS900_EDB_MASTER_EN equ	0x00002000
261 hidnplayr 371
;SIS900 Eeprom Access Reigster Bits
1254 hidnplayr 372
    SIS900_MDC	      equ      0x00000040
261 hidnplayr 373
    SIS900_MDDIR      equ      0x00000020
374
    SIS900_MDIO       equ      0x00000010  ; 7016 specific
375
    SIS900_EECS       equ      0x00000008
376
    SIS900_EECLK      equ      0x00000004
377
    SIS900_EEDO       equ      0x00000002
378
    SIS900_EEDI       equ      0x00000001
379
;SIS900 TX Configuration Register Bits
1254 hidnplayr 380
    SIS900_ATP	      equ      0x10000000 ;Automatic Transmit Padding
381
    SIS900_MLB	      equ      0x20000000 ;Mac Loopback Enable
382
    SIS900_HBI	      equ      0x40000000 ;HeartBeat Ignore (Req for full-dup)
383
    SIS900_CSI	      equ      0x80000000 ;CarrierSenseIgnore (Req for full-du
261 hidnplayr 384
;SIS900 RX Configuration Register Bits
385
    SIS900_AJAB       equ      0x08000000 ;
1254 hidnplayr 386
    SIS900_ATX	      equ      0x10000000 ;Accept Transmit Packets
387
    SIS900_ARP	      equ      0x40000000 ;accept runt packets (<64bytes)
388
    SIS900_AEP	      equ      0x80000000 ;accept error packets
261 hidnplayr 389
;SIS900 Interrupt Reigster Bits
1254 hidnplayr 390
    SIS900_WKEVT	   equ	    0x10000000
391
    SIS900_TxPAUSEEND	   equ	    0x08000000
392
    SIS900_TxPAUSE	   equ	    0x04000000
393
    SIS900_TxRCMP	   equ	    0x02000000
394
    SIS900_RxRCMP	   equ	    0x01000000
395
    SIS900_DPERR	   equ	    0x00800000
396
    SIS900_SSERR	   equ	    0x00400000
397
    SIS900_RMABT	   equ	    0x00200000
398
    SIS900_RTABT	   equ	    0x00100000
399
    SIS900_RxSOVR	   equ	    0x00010000
400
    SIS900_HIBERR	   equ	    0x00008000
401
    SIS900_SWINT	   equ	    0x00001000
402
    SIS900_MIBINT	   equ	    0x00000800
403
    SIS900_TxURN	   equ	    0x00000400
404
    SIS900_TxIDLE	   equ	    0x00000200
405
    SIS900_TxERR	   equ	    0x00000100
406
    SIS900_TxDESC	   equ	    0x00000080
407
    SIS900_TxOK 	   equ	    0x00000040
408
    SIS900_RxORN	   equ	    0x00000020
409
    SIS900_RxIDLE	   equ	    0x00000010
410
    SIS900_RxEARLY	   equ	    0x00000008
411
    SIS900_RxERR	   equ	    0x00000004
412
    SIS900_RxDESC	   equ	    0x00000002
413
    SIS900_RxOK 	   equ	    0x00000001
261 hidnplayr 414
;SIS900 Interrupt Enable Reigster Bits
1254 hidnplayr 415
    SIS900_IE	   equ	    0x00000001
261 hidnplayr 416
;SIS900 Revision ID
1254 hidnplayr 417
	SIS900B_900_REV       equ      0x03
418
	SIS630A_900_REV       equ      0x80
419
	SIS630E_900_REV       equ      0x81
420
	SIS630S_900_REV       equ      0x82
421
	SIS630EA1_900_REV     equ      0x83
422
	SIS630ET_900_REV      equ      0x84
423
	SIS635A_900_REV       equ      0x90
424
	SIS900_960_REV	      equ      0x91
261 hidnplayr 425
;SIS900 Receive Filter Control Register Bits
1254 hidnplayr 426
    SIS900_RFEN 	 equ 0x80000000
427
    SIS900_RFAAB	 equ 0x40000000
428
    SIS900_RFAAM	 equ 0x20000000
429
    SIS900_RFAAP	 equ 0x10000000
261 hidnplayr 430
    SIS900_RFPromiscuous equ 0x70000000
431
;SIS900 Reveive Filter Data Mask
432
    SIS900_RFDAT equ  0x0000FFFF
433
;SIS900 Eeprom Address
434
    SIS900_EEPROMSignature equ 0x00
435
    SIS900_EEPROMVendorID  equ 0x02
436
    SIS900_EEPROMDeviceID  equ 0x03
437
    SIS900_EEPROMMACAddr   equ 0x08
438
    SIS900_EEPROMChecksum  equ 0x0b
439
;The EEPROM commands include the alway-set leading bit.
440
;SIS900 Eeprom Command
1254 hidnplayr 441
    SIS900_EEread	   equ 0x0180
442
    SIS900_EEwrite	   equ 0x0140
443
    SIS900_EEerase	   equ 0x01C0
261 hidnplayr 444
    SIS900_EEwriteEnable   equ 0x0130
445
    SIS900_EEwriteDisable  equ 0x0100
1254 hidnplayr 446
    SIS900_EEeraseAll	   equ 0x0120
447
    SIS900_EEwriteAll	   equ 0x0110
448
    SIS900_EEaddrMask	   equ 0x013F
449
    SIS900_EEcmdShift	   equ 16
261 hidnplayr 450
;For SiS962 or SiS963, request the eeprom software access
1254 hidnplayr 451
	SIS900_EEREQ	equ 0x00000400
452
	SIS900_EEDONE	equ 0x00000200
453
	SIS900_EEGNT	equ 0x00000100
261 hidnplayr 454
 
1237 clevermous 455
SIS900_pci_revision equ ebx+device.pci_revision
456
sis900_get_mac_func equ ebx+device.get_MAC
457
sis900_special_func equ ebx+device.special_func
458
sis900_table_entries equ ebx+device.table_entries
459
cur_rx equ ebx+device.cur_rx
460
sys_msg_board_str equ SysMsgBoardStr
261 hidnplayr 461
;***************************************************************************
462
;   Function
463
;      SIS900_probe
464
;   Description
465
;      Searches for an ethernet card, enables it and clears the rx buffer
466
;      If a card was found, it enables the ethernet -> TCPIP link
467
;not done  - still need to probe mii transcievers
468
;***************************************************************************
469
if defined SIS900_DEBUG
470
SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0
471
end if
472
SIS900_probe:
473
;******Wake Up Chip*******
1237 clevermous 474
   stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x40, 0
261 hidnplayr 475
;*******Set some PCI Settings*********
476
   call    SIS900_adjust_pci_device
477
;*****Get Card Revision******
1237 clevermous 478
   stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x08
1254 hidnplayr 479
   mov [SIS900_pci_revision], al	;save the revision for later use
261 hidnplayr 480
;****** Look up through the sis900_specific_table
1254 hidnplayr 481
   mov	   esi,sis900_specific_table
261 hidnplayr 482
.probe_loop:
1254 hidnplayr 483
   cmp	   dword [esi],0		; Check if we reached end of the list
484
   je	   .probe_loop_failed
485
   cmp	   al,[esi]			; Check if revision is OK
486
   je	   .probe_loop_ok
487
   add	   esi,12			; Advance to next entry
488
   jmp	   .probe_loop
261 hidnplayr 489
.probe_loop_failed:
1254 hidnplayr 490
   jmp	   SIS900_Probe_Unsupported
261 hidnplayr 491
;*********Find Get Mac Function*********
492
.probe_loop_ok:
1254 hidnplayr 493
   mov	    eax,[esi+4] 	; Get pointer to "get MAC" function
494
   mov	    [sis900_get_mac_func],eax
495
   mov	    eax,[esi+8] 	; Get pointer to special initialization fn
496
   mov	    [sis900_special_func],eax
261 hidnplayr 497
;******** Get MAC ********
498
   call     dword [sis900_get_mac_func]
499
;******** Call special initialization fn if requested ********
1254 hidnplayr 500
   cmp	    dword [sis900_special_func],0
501
   je	    .no_special_init
261 hidnplayr 502
   call     dword [sis900_special_func]
503
.no_special_init:
504
;******** Set table entries ********
1254 hidnplayr 505
   mov	    al,[SIS900_pci_revision]
506
   cmp	    al,SIS635A_900_REV
507
   jae	    .ent16
508
   cmp	    al,SIS900B_900_REV
509
   je	    .ent16
510
   mov	    byte [sis900_table_entries],8
511
   jmp	    .ent8
261 hidnplayr 512
.ent16:
1254 hidnplayr 513
   mov	    byte [sis900_table_entries],16
261 hidnplayr 514
.ent8:
515
;*******Probe for mii transceiver*******
516
;TODO!!*********************
517
;*******Initialize Device*******
518
   call sis900_init
519
   ret
520
 
521
SIS900_Probe_Unsupported:
522
if defined SIS900_DEBUG
1254 hidnplayr 523
   mov	   esi, SIS900_Debug_Str_Unsupported
261 hidnplayr 524
   call    sys_msg_board_str
525
end if
1254 hidnplayr 526
   or	   eax, -1
261 hidnplayr 527
   ret
528
;***************************************************************************
529
; Function: sis900_init
530
;
531
; Description: resets the ethernet controller chip and various
532
;    data structures required for sending and receiving packets.
533
;
534
; Arguments:
535
;
536
; returns:   none
537
;not done
538
;***************************************************************************
539
sis900_init:
1254 hidnplayr 540
   call SIS900_reset		   ;Done
261 hidnplayr 541
   call SIS900_init_rxfilter   ;Done
542
   call SIS900_init_txd        ;Done
1254 hidnplayr 543
   call SIS900_init_rxd 	   ;Done
261 hidnplayr 544
   call SIS900_set_rx_mode     ;done
545
   call SIS900_set_tx_mode
546
   ;call SIS900_check_mode
1237 clevermous 547
; enable interrupts on packet receive
548
	xor	eax, eax
549
	inc	eax	; eax = 1 = SIS900_RxOK
550
	mov	edx, [ebx+device.io_addr]
551
	add	edx, SIS900_imr
552
	out	dx, eax
553
; globally enable interrupts
554
	add	edx, SIS900_ier-SIS900_imr
1254 hidnplayr 555
	out	dx, eax ; eax is still 1
1237 clevermous 556
	xor	eax, eax
261 hidnplayr 557
   ret
558
 
559
;***************************************************************************
560
;   Function
561
;      SIS900_reset
562
;   Description
563
;      disables interrupts and soft resets the controller chip
564
;
565
;done+
566
;***************************************************************************
567
if defined SIS900_DEBUG
568
   SIS900_Debug_Reset_Failed db 'Reset Failed ',0
569
end if
570
SIS900_reset:
1237 clevermous 571
	movzx	eax, [ebx+device.irq_line]
1254 hidnplayr 572
	stdcall AttachIntHandler, eax, int_handler, 0
1237 clevermous 573
   push     ebp
1254 hidnplayr 574
   mov	    ebp, [ebx+device.io_addr] ; base address
261 hidnplayr 575
   ;******Disable Interrupts and reset Receive Filter*******
1254 hidnplayr 576
   xor	    eax, eax		; 0 to initialize
577
   lea	    edx,[ebp+SIS900_ier]
578
   out	    dx, eax			; Write 0 to location
579
   lea	    edx,[ebp+SIS900_imr]
580
   out	    dx, eax			; Write 0 to location
581
   lea	    edx,[ebp+SIS900_rfcr]
582
   out	    dx, eax			; Write 0 to location
261 hidnplayr 583
   ;*******Reset Card***********************************************
1254 hidnplayr 584
   lea	    edx,[ebp+SIS900_cr]
585
   in	    eax, dx				; Get current Command Register
586
   or	    eax, SIS900_RESET		; set flags
587
   or	    eax, SIS900_RxRESET     ;
588
   or		eax, SIS900_TxRESET	    ;
589
   out	    dx, eax				; Write new Command Register
261 hidnplayr 590
   ;*******Wait Loop************************************************
1237 clevermous 591
   push     ebx
1254 hidnplayr 592
   lea	    edx,[ebp+SIS900_isr]
593
   mov	    ecx, 0x03000000	    ; Status we would like to see from card
594
   mov	    ebx, 2001		    ; only loop 1000 times
261 hidnplayr 595
SIS900_Wait:
1254 hidnplayr 596
   dec	    ebx 				    ; 1 less loop
597
   jz	    SIS900_DoneWait_e		; 1000 times yet?
598
   in	    eax, dx				    ; move interrup status to eax
599
   and	    eax, ecx
600
   xor	    ecx, eax
601
   jz	    SIS900_DoneWait
602
   jmp	    SIS900_Wait
261 hidnplayr 603
SIS900_DoneWait_e:
604
if defined SIS900_DEBUG
605
   mov esi, SIS900_Debug_Reset_Failed
606
   call sys_msg_board_str
607
end if
608
SIS900_DoneWait:
1254 hidnplayr 609
   pop	    ebx
261 hidnplayr 610
   ;*******Set Configuration Register depending on Card Revision********
1254 hidnplayr 611
   lea	    edx,[ebp+SIS900_cfg]
612
   mov	    eax, SIS900_PESEL		    ; Configuration Register Bit
613
   mov	    cl, [SIS900_pci_revision]	; card revision
614
   cmp	    cl, SIS635A_900_REV
615
   je	    SIS900_RevMatch
616
   cmp	    cl, SIS900B_900_REV 	; Check card revision
617
   je	    SIS900_RevMatch
618
   out	    dx, eax				    ; no revision match
619
   jmp	    SIS900_Reset_Complete
620
SIS900_RevMatch:					; Revision match
621
   or	    eax, SIS900_RND_CNT 	; Configuration Register Bit
622
   out	    dx, eax
261 hidnplayr 623
SIS900_Reset_Complete:
1254 hidnplayr 624
   xor	    eax, eax
625
   pop	    ebp
261 hidnplayr 626
   ret
627
 
628
;***************************************************************************
629
; Function: sis_init_rxfilter
630
;
631
; Description: sets receive filter address to our MAC address
632
;
633
; Arguments:
634
;
635
; returns:
636
;done+
637
;***************************************************************************
638
SIS900_init_rxfilter:
1237 clevermous 639
   push     ebp
1254 hidnplayr 640
   mov	    ebp, [ebx+device.io_addr]	; base address
261 hidnplayr 641
   ;****Get Receive Filter Control Register ********
1254 hidnplayr 642
   lea	    edx,[ebp+SIS900_rfcr]
643
   in	    eax, dx			    ; get register
261 hidnplayr 644
   push     eax
645
   ;****disable packet filtering before setting filter*******
1254 hidnplayr 646
   mov	    eax, SIS900_RFEN	;move receive filter enable flag
647
   not	    eax 			;1s complement
648
   and	    eax, [esp]			;disable receiver
649
   out	    dx, eax			;set receive disabled
261 hidnplayr 650
   ;********load MAC addr to filter data register*********
1254 hidnplayr 651
   xor	    ecx, ecx
261 hidnplayr 652
SIS900_RXINT_Mac_Write:
653
   ;high word of eax tells card which mac byte to write
1254 hidnplayr 654
   mov	    eax, ecx
655
   lea	    edx,[ebp+SIS900_rfcr]
656
   shl	    eax, 16						;
657
   out	    dx, eax						;
658
   lea	    edx,[ebp+SIS900_rfdr]
659
   mov	    ax,  word [ebx+device.mac+ecx*2] ; Get Mac ID word
660
   out	    dx, ax						; Send Mac ID
661
   inc	    cl							; send next word
662
   cmp	    cl, 3						; more to send?
663
   jne	    SIS900_RXINT_Mac_Write
261 hidnplayr 664
   ;********enable packet filitering *****
1254 hidnplayr 665
   pop	    eax 			    ;old register value
666
   lea	    edx,[ebp+SIS900_rfcr]
667
   or	    eax, SIS900_RFEN	;enable filtering
668
   out	    dx, eax		;set register
669
   pop	    ebp
261 hidnplayr 670
   ret
671
 
672
;***************************************************************************
673
;*
674
;* Function: sis_init_txd
675
;*
676
;* Description: initializes the Tx descriptor
677
;*
678
;* Arguments:
679
;*
680
;* returns:
681
;*done
682
;***************************************************************************
683
SIS900_init_txd:
684
   ;********** initialize TX descriptor **************
1254 hidnplayr 685
   mov	   [ebx+device.txd], dword 0	   ;put link to next descriptor in link field
686
   mov	   [ebx+device.txd+4],dword 0	   ;clear status field
687
   lea	   eax, [ebx+0x1000]
1237 clevermous 688
   call    GetPgAddr
1254 hidnplayr 689
   mov	   [ebx+device.txd+8], eax   ;save address to buffer ptr field
261 hidnplayr 690
   ;*************** load Transmit Descriptor Register ***************
1254 hidnplayr 691
   mov	   edx, [ebx+device.io_addr]	    ; base address
692
   add	   edx, SIS900_txdp	 ; TX Descriptor Pointer
693
   add	   eax, device.txd - 0x1000	   ; First Descriptor
694
   out	   dx, eax			       ; move the pointer
261 hidnplayr 695
   ret
696
 
697
;***************************************************************************
698
;* Function: sis_init_rxd
699
;*
700
;* Description: initializes the Rx descriptor ring
701
;*
702
;* Arguments:
703
;*
704
;* Returns:
705
;*done
706
;***************************************************************************
707
SIS900_init_rxd:
1254 hidnplayr 708
   xor	    ecx,ecx
709
   mov	    [cur_rx], cl					;Set cuurent rx discriptor to 0
710
   mov	    eax, ebx
1237 clevermous 711
   call     GetPgAddr
1254 hidnplayr 712
   mov	    esi, eax
261 hidnplayr 713
   ;******** init RX descriptors ********
714
SIS900_init_rxd_Loop:
1254 hidnplayr 715
    mov     edx, ecx					    ;current descriptor
716
    imul    edx, 12			    ;
717
    mov     eax, ecx					    ;determine next link descriptor
718
    inc     eax 			    ;
719
    cmp     eax, NUM_RX_DESC		    ;
720
    jne     SIS900_init_rxd_Loop_0	    ;
721
    xor     eax, eax			    ;
722
SIS900_init_rxd_Loop_0: 		   ;
723
    imul    eax, 12			    ;
1237 clevermous 724
    lea     eax, [eax+esi+device.rxd]
1254 hidnplayr 725
    mov     [ebx+device.rxd+edx], eax					   ;save link to next descriptor
726
    mov     [ebx+device.rxd+edx+4],dword RX_BUFF_SZ	   ;status bits init to buf size
727
    mov     eax, ecx						;find where the buf is located
728
    imul    eax,RX_BUFF_SZ		    ;
1237 clevermous 729
    lea     eax, [eax+esi+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
1254 hidnplayr 730
    mov     [ebx+device.rxd+edx+8], eax 			   ;save buffer pointer
731
    inc     ecx 						    ;next descriptor
732
    cmp     ecx, NUM_RX_DESC		    ;
733
    jne     SIS900_init_rxd_Loop	    ;
261 hidnplayr 734
    ;********* load Receive Descriptor Register with address of first
735
    ; descriptor*********
1237 clevermous 736
    mov     edx, [ebx+device.io_addr]
737
    add     edx, SIS900_rxdp
738
    lea     eax, [esi+device.rxd]
261 hidnplayr 739
    out     dx, eax
740
    ret
741
 
742
;***************************************************************************
743
;* Function: sis900_set_tx_mode
744
;*
745
;* Description:
746
;*    sets the transmit mode to allow for full duplex
747
;*
748
;*
749
;* Arguments:
750
;*
751
;* Returns:
752
;*
753
;* Comments:
754
;*     If you are having problems transmitting packet try changing the
755
;*     Max DMA Burst, Possible settings are as follows:
756
;*         0x00000000 = 512 bytes
757
;*         0x00100000 = 4 bytes
758
;*         0x00200000 = 8 bytes
759
;*         0x00300000 = 16 bytes
760
;*         0x00400000 = 32 bytes
761
;*         0x00500000 = 64 bytes
762
;*         0x00600000 = 128 bytes
763
;*         0x00700000 = 256 bytes
764
;***************************************************************************
765
SIS900_set_tx_mode:
1237 clevermous 766
   push     ebp
1254 hidnplayr 767
   mov	    ebp,[ebx+device.io_addr]
768
   lea	    edx,[ebp+SIS900_cr]
769
   in	    eax, dx			    ; Get current Command Register
770
   or	    eax, SIS900_TxENA	;Enable Receive
771
   out	    dx, eax
772
   lea	    edx,[ebp+SIS900_txcfg]; Transmit config Register offset
773
   mov	    eax, SIS900_ATP		;allow automatic padding
774
   or	    eax, SIS900_HBI		;allow heartbeat ignore
775
   or	    eax, SIS900_CSI		;allow carrier sense ignore
776
   or	    eax, 0x00600000	;Max DMA Burst
777
   or	    eax, 0x00000100	;TX Fill Threshold
778
   or	    eax, 0x00000020	;TX Drain Threshold
779
   out	    dx, eax
780
   pop	    ebp
261 hidnplayr 781
   ret
782
 
783
;***************************************************************************
784
;* Function: sis900_set_rx_mode
785
;*
786
;* Description:
787
;*    sets the receive mode to accept all broadcast packets and packets
788
;*    with our MAC address, and reject all multicast packets.  Also allows
789
;*    full-duplex
790
;*
791
;* Arguments:
792
;*
793
;* Returns:
794
;*
795
;* Comments:
796
;*     If you are having problems receiving packet try changing the
797
;*     Max DMA Burst, Possible settings are as follows:
798
;*         0x00000000 = 512 bytes
799
;*         0x00100000 = 4 bytes
800
;*         0x00200000 = 8 bytes
801
;*         0x00300000 = 16 bytes
802
;*         0x00400000 = 32 bytes
803
;*         0x00500000 = 64 bytes
804
;*         0x00600000 = 128 bytes
805
;*         0x00700000 = 256 bytes
806
;***************************************************************************
807
SIS900_set_rx_mode:
1237 clevermous 808
   push     ebp
1254 hidnplayr 809
   mov	    ebp,[ebx+device.io_addr]
261 hidnplayr 810
    ;**************update Multicast Hash Table in Receive Filter
1254 hidnplayr 811
   xor	    cl, cl
261 hidnplayr 812
SIS900_set_rx_mode_Loop:
1254 hidnplayr 813
   mov	    eax, ecx
814
   shl	    eax, 1
815
   lea	    edx,[ebp+SIS900_rfcr]	    ; Receive Filter Control Reg offset
816
   mov	    eax, 4					    ;determine table entry
817
   add	    al, cl
818
   shl	    eax, 16
819
   out	    dx, eax					    ;tell card which entry to modify
820
   lea	    edx,[ebp+SIS900_rfdr]	    ; Receive Filter Control Reg offset
821
   mov	    eax, 0xffff 			    ;entry value
822
   out	    dx, ax					    ;write value to table in card
823
   inc	    cl						    ;next entry
824
   cmp	    cl,[sis900_table_entries]	;
825
   jl	    SIS900_set_rx_mode_Loop
261 hidnplayr 826
   ;*******Set Receive Filter Control Register*************
1254 hidnplayr 827
   lea	    edx,[ebp+SIS900_rfcr]	; Receive Filter Control Register offset
828
   mov	    eax, SIS900_RFAAB		;accecpt all broadcast packets
829
   or	    eax, SIS900_RFAAM		;accept all multicast packets
830
   or	    eax, SIS900_RFAAP		;Accept all packets
831
   or	    eax, SIS900_RFEN		;enable receiver filter
832
   out	    dx, eax
261 hidnplayr 833
   ;******Enable Receiver************
1254 hidnplayr 834
   lea	    edx,[ebp+SIS900_cr] ; Command Register offset
835
   in	    eax, dx			    ; Get current Command Register
836
   or	    eax, SIS900_RxENA	;Enable Receive
837
   out	    dx, eax
261 hidnplayr 838
   ;*********Set
1254 hidnplayr 839
   lea	    edx,[ebp+SIS900_rxcfg]	; Receive Config Register offset
840
   mov	    eax, SIS900_ATX			;Accept Transmit Packets
841
				    ; (Req for full-duplex and PMD Loopback)
842
   or	    eax, 0x00600000			;Max DMA Burst
843
   or	    eax, 0x00000002			;RX Drain Threshold, 8X8 bytes or 64bytes
844
   out	    dx, eax					;
845
   pop	    ebp
261 hidnplayr 846
   ret
847
 
848
;***************************************************************************
849
; *     SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
850
; *     @pci_dev: the sis900 pci device
851
; *     @net_dev: the net device to get address for
852
; *
853
; *     SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
854
; *     is shared by
855
; *     LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
856
; *     and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
857
; *     by LAN, otherwise is not. After MAC address is read from EEPROM, send
858
; *     EEDONE signal to refuse EEPROM access by LAN.
859
; *     The EEPROM map of SiS962 or SiS963 is different to SiS900.
860
; *     The signature field in SiS962 or SiS963 spec is meaningless.
861
; *     MAC address is read into @net_dev->dev_addr.
862
; *done
863
;*
864
;* Return 0 is EAX = failure
865
;*Done+
866
;***************************************************************************
867
if defined SIS900_DEBUG
868
SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0
869
SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0
870
SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0
871
SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0
872
end if
873
SIS960_get_mac_addr:
1237 clevermous 874
   push     ebp
1254 hidnplayr 875
   mov	    ebp,[ebx+device.io_addr]
261 hidnplayr 876
   ;**********Send Request for eeprom access*********************
1254 hidnplayr 877
   lea	    edx,[ebp+SIS900_mear]		; Eeprom access register
878
   mov	    eax, SIS900_EEREQ			; Request access to eeprom
879
   out	    dx, eax						; Send request
880
   xor	    ecx,ecx						;
261 hidnplayr 881
   ;******Loop 4000 times and if access not granted error out*****
882
SIS96X_Get_Mac_Wait:
1254 hidnplayr 883
   in	    eax, dx					;get eeprom status
884
   and	    eax, SIS900_EEGNT	    ;see if eeprom access granted flag is set
885
   jnz	    SIS900_Got_EEP_Access	;if it is, go access the eeprom
886
   inc	    ecx 					;else keep waiting
887
   cmp	    ecx, 4000				;have we tried 4000 times yet?
888
   jl	    SIS96X_Get_Mac_Wait     ;if not ask again
889
   xor	    eax, eax		    ;return zero in eax indicating failure
261 hidnplayr 890
   ;*******Debug **********************
891
if defined SIS900_DEBUG
892
   mov esi,SIS900_Debug_Str_GetMac_Failed
893
   call sys_msg_board_str
894
end if
895
   jmp SIS960_get_mac_addr_done
896
   ;**********EEprom access granted, read MAC from card*************
897
SIS900_Got_EEP_Access:
898
    ; zero based so 3-16 bit reads will take place
1254 hidnplayr 899
   mov	    ecx, 2
261 hidnplayr 900
SIS96x_mac_read_loop:
1254 hidnplayr 901
   mov	    eax, SIS900_EEPROMMACAddr	 ;Base Mac Address
902
   add	    eax, ecx				     ;Current Mac Byte Offset
261 hidnplayr 903
   push     ecx
1254 hidnplayr 904
   call     sis900_read_eeprom		 ;try to read 16 bits
905
   pop	    ecx
906
   mov	    word [ebx+device.mac+ecx*2], ax	   ;save 16 bits to the MAC ID varible
907
   dec	    ecx 			 ;one less word to read
908
   jns	    SIS96x_mac_read_loop	 ;if more read more
909
   mov	    eax, 1			 ;return non-zero indicating success
261 hidnplayr 910
   ;*******Debug Print MAC ID to debug window**********************
911
if defined SIS900_DEBUG
912
   mov esi,SIS900_Debug_Str_GetMac_Address2
913
   call sys_msg_board_str
1237 clevermous 914
   lea edx, [ebx+device.mac]
261 hidnplayr 915
   call Create_Mac_String
916
end if
917
   ;**********Tell EEPROM We are Done Accessing It*********************
918
SIS960_get_mac_addr_done:
1254 hidnplayr 919
   lea	    edx,[ebp+SIS900_mear]		; Eeprom access register
920
   mov	    eax, SIS900_EEDONE		 ;tell eeprom we are done
921
   out	    dx,eax
922
   pop	    ebp
261 hidnplayr 923
   ret
924
;***************************************************************************
925
;*      sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
926
;*      @pci_dev: the sis900 pci device
927
;*      @net_dev: the net device to get address for
928
;*
929
;*      Older SiS900 and friends, use EEPROM to store MAC address.
930
;*      MAC address is read from read_eeprom() into @net_dev->dev_addr.
931
;* done/untested
932
;***************************************************************************
933
SIS900_get_mac_addr:
934
   ;*******Debug **********************
935
if defined SIS900_DEBUG
936
   mov esi,SIS900_Debug_Str_GetMac_Start
937
   call sys_msg_board_str
938
end if
939
   ;******** check to see if we have sane EEPROM *******
1254 hidnplayr 940
   mov	    eax, SIS900_EEPROMSignature  ;Base Eeprom Signature
941
   call     sis900_read_eeprom		 ;try to read 16 bits
261 hidnplayr 942
   cmp ax, 0xffff
943
   je SIS900_Bad_Eeprom
944
   cmp ax, 0
945
   je SIS900_Bad_Eeprom
946
   ;**************Read MacID**************
947
   ; zero based so 3-16 bit reads will take place
1254 hidnplayr 948
   mov	    ecx, 2
261 hidnplayr 949
SIS900_mac_read_loop:
1254 hidnplayr 950
   mov	    eax, SIS900_EEPROMMACAddr	 ;Base Mac Address
951
   add	    eax, ecx				     ;Current Mac Byte Offset
261 hidnplayr 952
   push     ecx
1254 hidnplayr 953
   call     sis900_read_eeprom		 ;try to read 16 bits
954
   pop	    ecx
955
   mov	    word [ebx+device.mac+ecx*2], ax	   ;save 16 bits to the MAC ID storage
956
   dec	    ecx 			 ;one less word to read
957
   jns	    SIS900_mac_read_loop	 ;if more read more
958
   mov	    eax, 1			 ;return non-zero indicating success
261 hidnplayr 959
   ;*******Debug Print MAC ID to debug window**********************
960
if defined SIS900_DEBUG
961
   mov esi,SIS900_Debug_Str_GetMac_Address
962
   call sys_msg_board_str
1237 clevermous 963
   lea edx, [ebx+device.mac]
261 hidnplayr 964
   call Create_Mac_String
965
end if
966
   ret
967
 
968
SIS900_Bad_Eeprom:
969
   xor eax, eax
970
   ;*******Debug **********************
971
if defined SIS900_DEBUG
972
   mov esi,SIS900_Debug_Str_GetMac_Failed
973
   call sys_msg_board_str
974
end if
975
   ret
976
;***************************************************************************
977
;*      Get_Mac_SIS635_900_REV: - Get MAC address for model 635
978
;*
979
;*
980
;***************************************************************************
981
Get_Mac_SIS635_900_REV:
982
if defined SIS900_DEBUG
983
    mov     esi,SIS900_Debug_Str_GetMac_Start
984
    call    sys_msg_board_str
985
end if
1237 clevermous 986
    push    ebp
987
    mov     ebp,[ebx+device.io_addr]
261 hidnplayr 988
    lea     edx,[ebp+SIS900_rfcr]
1254 hidnplayr 989
    in	    eax,dx
261 hidnplayr 990
    mov     edi,eax ; EDI=rfcrSave
991
    lea     edx,[ebp+SIS900_cr]
1254 hidnplayr 992
    or	    eax,SIS900_RELOAD
261 hidnplayr 993
    out     dx,eax
994
    xor     eax,eax
995
    out     dx,eax
996
    ; Disable packet filtering before setting filter
997
    lea     edx,[ebp+SIS900_rfcr]
998
    mov     eax,edi
999
    and     edi,not SIS900_RFEN
1000
    out     dx,eax
1001
    ; Load MAC to filter data register
1002
    xor     ecx,ecx
1237 clevermous 1003
    lea     esi,[ebx+device.mac]
261 hidnplayr 1004
.get_mac_loop:
1005
    lea     edx,[ebp+SIS900_rfcr]
1006
    mov     eax,ecx
1007
    shl     eax,SIS900_RFADDR_shift
1008
    out     dx,eax
1009
    lea     edx,[ebp+SIS900_rfdr]
1254 hidnplayr 1010
    in	    eax,dx
261 hidnplayr 1011
    mov     [esi],ax
1012
    add     esi,2
1013
    inc     ecx
1014
    cmp     ecx,3
1015
    jne .get_mac_loop
1016
    ; Enable packet filtering
1017
    ;lea     edx,[ebp+SIS900_rfcr]
1018
    ;mov     eax,edi
1019
    ;or      eax,SIS900_RFEN
1020
    ;out     dx, eax
1021
   ;*******Debug Print MAC ID to debug window**********************
1022
if defined SIS900_DEBUG
1023
    mov     esi,SIS900_Debug_Str_GetMac_Address
1024
    call    sys_msg_board_str
1237 clevermous 1025
    lea     edx, [ebx+device.mac]
261 hidnplayr 1026
    call    Create_Mac_String
1027
end if
1237 clevermous 1028
    pop     ebp
261 hidnplayr 1029
    ret
1030
;***************************************************************************
1031
;* Function: sis900_read_eeprom
1032
;*
1033
;* Description: reads and returns a given location from EEPROM
1034
;*
1035
;* Arguments: eax - location:       requested EEPROM location
1036
;*
1037
;* Returns:   eax :                contents of requested EEPROM location
1038
;*
1039
; Read Serial EEPROM through EEPROM Access Register, Note that location is
1040
;   in word (16 bits) unit */
1041
;done+
1042
;***************************************************************************
1043
sis900_read_eeprom:
1044
   push      esi
1045
   push      edx
1046
   push      ecx
1047
   push      ebx
1237 clevermous 1048
   push      ebp
1254 hidnplayr 1049
   mov	     ebp,[ebx+device.io_addr]
1050
   mov	     ebx, eax		   ;location of Mac byte to read
1051
   or	     ebx, SIS900_EEread    ;
1052
   lea	     edx,[ebp+SIS900_mear] ; Eeprom access register
1053
   xor	     eax, eax		   ; start send
1054
   out	     dx,eax
261 hidnplayr 1055
   call      SIS900_Eeprom_Delay_1
1254 hidnplayr 1056
   mov	     eax, SIS900_EECLK
1057
   out	     dx, eax
261 hidnplayr 1058
   call      SIS900_Eeprom_Delay_1
1059
    ;************ Shift the read command (9) bits out. *********
1254 hidnplayr 1060
   mov	     cl, 8					;
261 hidnplayr 1061
sis900_read_eeprom_Send:
1254 hidnplayr 1062
   mov	     eax, 1
1063
   shl	     eax, cl
1064
   and	     eax, ebx
261 hidnplayr 1065
   jz SIS900_Read_Eeprom_8
1254 hidnplayr 1066
   mov	     eax, 9
1067
   jmp	     SIS900_Read_Eeprom_9
261 hidnplayr 1068
SIS900_Read_Eeprom_8:
1254 hidnplayr 1069
   mov	     eax, 8
261 hidnplayr 1070
SIS900_Read_Eeprom_9:
1254 hidnplayr 1071
   out	     dx, eax
261 hidnplayr 1072
   call      SIS900_Eeprom_Delay_1
1254 hidnplayr 1073
   or	     eax, SIS900_EECLK
1074
   out	     dx, eax
261 hidnplayr 1075
   call      SIS900_Eeprom_Delay_1
1254 hidnplayr 1076
   cmp	     cl, 0
1077
   je	     sis900_read_eeprom_Send_Done
1078
   dec	     cl
1079
   jmp	     sis900_read_eeprom_Send
261 hidnplayr 1080
   ;*********************
1081
sis900_read_eeprom_Send_Done:
1254 hidnplayr 1082
   mov	     eax, SIS900_EECS		;
1083
   out	     dx, eax
261 hidnplayr 1084
   call      SIS900_Eeprom_Delay_1
1085
    ;********** Read 16-bits of data in ***************
1254 hidnplayr 1086
    mov      cx, 16				;16 bits to read
261 hidnplayr 1087
sis900_read_eeprom_Send2:
1088
    mov      eax, SIS900_EECS
1089
    out      dx, eax
1090
    call     SIS900_Eeprom_Delay_1
1254 hidnplayr 1091
    or	     eax, SIS900_EECLK
261 hidnplayr 1092
    out      dx, eax
1093
    call     SIS900_Eeprom_Delay_1
1254 hidnplayr 1094
    in	     eax, dx
261 hidnplayr 1095
    shl      ebx, 1
1096
    and      eax, SIS900_EEDO
1254 hidnplayr 1097
    jz	     SIS900_Read_Eeprom_0
1098
    or	     ebx, 1
261 hidnplayr 1099
SIS900_Read_Eeprom_0:
1254 hidnplayr 1100
   dec	     cx
1101
   jnz	     sis900_read_eeprom_Send2
261 hidnplayr 1102
   ;************** Terminate the EEPROM access. **************
1254 hidnplayr 1103
   xor	     eax, eax
1104
   out	     dx, eax
261 hidnplayr 1105
   call      SIS900_Eeprom_Delay_1
1254 hidnplayr 1106
   mov	     eax, SIS900_EECLK
1107
   out	     dx, eax
1108
   mov	     eax, ebx
1109
   and	     eax, 0x0000ffff			;return only 16 bits
1110
   pop	     ebp
1111
   pop	     ebx
1112
   pop	     ecx
1113
   pop	     edx
1114
   pop	     esi
261 hidnplayr 1115
   ret
1116
;***************************************************************************
1117
;   Function
1118
;      SIS900_Eeprom_Delay_1
1119
;   Description
1120
;
1121
;
1122
;
1123
;
1124
;***************************************************************************
1125
SIS900_Eeprom_Delay_1:
1126
   push eax
1127
   in eax, dx
1128
   pop eax
1129
   ret
1130
 
1237 clevermous 1131
write_mac:
1132
	DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n'
1133
	add	esp, 6
1134
	ret
1135
 
261 hidnplayr 1136
;***************************************************************************
1137
;   Function
1237 clevermous 1138
;      int_handler
261 hidnplayr 1139
;   Description
1237 clevermous 1140
;      handles received IRQs, which signal received packets
261 hidnplayr 1141
;
1142
;  Currently only supports one descriptor per packet, if packet is fragmented
1143
;  between multiple descriptors you will lose part of the packet
1144
;***************************************************************************
1145
if defined SIS900_DEBUG
1146
SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0
1147
SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0
1148
SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0
1149
end if
1237 clevermous 1150
int_handler:
1151
; find pointer of device which made IRQ occur
1152
	mov	esi, DEV_LIST
1153
	mov	ecx, [NUM_DEV]
1154
	test	ecx, ecx
1155
	jz	.nothing
1156
.nextdevice:
1157
	mov	ebx, [esi]
1158
	mov	edx, [ebx+device.io_addr]
1159
	add	edx, SIS900_isr
1254 hidnplayr 1160
	in	eax, dx ; note that this clears all interrupts
1237 clevermous 1161
	test	al, SIS900_RxOK
1162
	jnz	.got_it
1163
	loop	.nextdevice
1164
.nothing:
1165
	ret
1166
.got_it:
261 hidnplayr 1167
    ;**************Get Status **************
1254 hidnplayr 1168
    movzx     eax, [ebx+device.cur_rx]		;find current discriptor
1169
    imul      eax, 12		    ;
1170
    mov       ecx, [ebx+device.rxd+eax+4]	   ; get receive status
261 hidnplayr 1171
    ;**************Check Status **************
1172
    ;Check RX_Status to see if packet is waiting
1237 clevermous 1173
    test      ecx, 0x80000000
261 hidnplayr 1174
    jnz       SIS900_poll_IS_packet
1175
    ret
1176
   ;**********There is a packet waiting check it for errors**************
1177
SIS900_poll_IS_packet:
1254 hidnplayr 1178
    test      ecx, 0x67C0000		;see if there are any errors
261 hidnplayr 1179
    jnz       SIS900_Poll_Error_Status
1180
   ;**************Check size of packet*************
1254 hidnplayr 1181
   and	     ecx, SIS900_DSIZE					;get packet size minus CRC
1182
   cmp	     ecx, SIS900_CRC_SIZE
261 hidnplayr 1183
   ;make sure packet contains data
1254 hidnplayr 1184
   jle	     SIS900_Poll_Error_Size
261 hidnplayr 1185
   ;*******Copy Good Packet to receive buffer******
1254 hidnplayr 1186
   sub	    ecx, SIS900_CRC_SIZE			     ;dont want crc
1237 clevermous 1187
   ; update statistics
1254 hidnplayr 1188
   inc	    dword [ebx+device.packets_rx]
1189
   add	    dword [ebx+device.bytes_rx], ecx
1190
   adc	    dword [ebx+device.bytes_rx+4], 0
1237 clevermous 1191
   push     ecx
1192
   stdcall  KernelAlloc, ecx
1254 hidnplayr 1193
   pop	    ecx
1237 clevermous 1194
   test     eax, eax
1254 hidnplayr 1195
   jz	    int_handler.nothing
1237 clevermous 1196
   push     ebx
1197
   push     .return ; return address for EthReceiver
261 hidnplayr 1198
   ;**********Continue copying packet****************
1237 clevermous 1199
   push     ecx eax ; save buffer pointer and size for EthReceiver
1254 hidnplayr 1200
   mov	    edi, eax
1237 clevermous 1201
   movzx    esi, byte [ebx+device.cur_rx]
1202
   imul     esi, RX_BUFF_SZ
1254 hidnplayr 1203
   lea	    esi, [esi+ebx+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
261 hidnplayr 1204
   ; first copy dword-wise, divide size by 4
1254 hidnplayr 1205
   shr	    ecx, 2
1206
   rep	    movsd							; copy the dwords
1207
   mov	    ecx, [esp+4]
1208
   and	    ecx, 3						    ;
1209
   rep	    movsb
261 hidnplayr 1210
   ;********Debug, tell user we have a good packet*************
1211
if defined SIS900_DEBUG
1254 hidnplayr 1212
   mov	    esi, SIS900_Debug_Pull_Packet_good
261 hidnplayr 1213
   call     sys_msg_board_str
1214
end if
1254 hidnplayr 1215
   jmp	    EthReceiver
1237 clevermous 1216
.return:
1254 hidnplayr 1217
   pop	    ebx
1218
   jmp	    SIS900_Poll_Cnt
261 hidnplayr 1219
   ;*************Error occured let user know through debug window***********
1220
SIS900_Poll_Error_Status:
1221
if defined SIS900_DEBUG
1254 hidnplayr 1222
		mov	 esi, SIS900_Debug_Pull_Bad_Packet_Status
1223
		call	 sys_msg_board_str
261 hidnplayr 1224
end if
1254 hidnplayr 1225
		jmp	 SIS900_Poll_Cnt
261 hidnplayr 1226
SIS900_Poll_Error_Size:
1227
if defined SIS900_DEBUG
1254 hidnplayr 1228
		mov	 esi, SIS900_Debug_Pull_Bad_Packet_Size
1229
		call	 sys_msg_board_str
261 hidnplayr 1230
end if
1231
   ;*************Increment to next available descriptor**************
1232
SIS900_Poll_Cnt:
1233
    ;Reset status, allow ethernet card access to descriptor
1237 clevermous 1234
   movzx    eax, [ebx+device.cur_rx]
1254 hidnplayr 1235
   lea	    eax, [eax*3]
1236
   mov	    ecx, RX_BUFF_SZ
1237
   mov	    [ebx+device.rxd+eax*4+4], ecx		 ;
1238
   inc	    [ebx+device.cur_rx] 			 ;get next descriptor
1239
   and	    [ebx+device.cur_rx],NUM_RX_DESC-1		 ;only 4 descriptors 0-3
261 hidnplayr 1240
   ;******Enable Receiver************
1254 hidnplayr 1241
   mov	    edx, [ebx+device.io_addr]
1242
   add	    edx, SIS900_cr ; Command Register offset
1243
   in	    eax, dx			    ; Get current Command Register
1244
   or	    eax, SIS900_RxENA	;Enable Receive
1245
   out	    dx, eax
261 hidnplayr 1246
   ret
1247
;***************************************************************************
1248
;   Function
1237 clevermous 1249
;      transmit
261 hidnplayr 1250
;   Description
1251
;      Transmits a packet of data via the ethernet card
1254 hidnplayr 1252
;         buffer pointer in [esp+4]
1253
;         size of buffer in [esp+8]
1237 clevermous 1254
;         pointer to device structure in ebx
261 hidnplayr 1255
;
1256
;      only one transmit descriptor is used
1257
;
1258
;***************************************************************************
1259
if defined SIS900_DEBUG
1260
SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0
1261
SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0
1262
end if
735 diamond 1263
str1 db 'Transmitting packet:',13,10,0
1264
str2 db ' ',0
1237 clevermous 1265
transmit:
1254 hidnplayr 1266
   cmp	    dword [esp+8], MAX_ETH_FRAME_SIZE
1267
   jg	    transmit_finish
1268
   cmp	    dword [esp+8], 60
1269
   jl	    transmit_finish
1237 clevermous 1270
   push     ebp
1254 hidnplayr 1271
   mov	    ebp, [ebx+device.io_addr] ; Base Address
261 hidnplayr 1272
   ;******** Stop the transmitter ********
1254 hidnplayr 1273
   lea	    edx,[ebp+SIS900_cr] ; Command Register offset
1274
   in	    eax, dx			    ; Get current Command Register
1275
   or	    eax, SIS900_TxDIS	; Disable Transmitter
1276
   out	    dx, eax
261 hidnplayr 1277
   ;*******load Transmit Descriptor Register *******
1254 hidnplayr 1278
   lea	    edx,[ebp+SIS900_txdp]
1279
   mov	    eax, ebx
1237 clevermous 1280
   call     GetPgAddr
1254 hidnplayr 1281
   add	    eax, device.txd
1282
   out	    dx, eax
261 hidnplayr 1283
   ;******* copy packet to descriptor*******
1254 hidnplayr 1284
   mov	   esi, [esp+8]
1285
   lea	   edi, [ebx+0x1000]
1286
   mov	   ecx, [esp+12]
1287
   mov	   edx, ecx
1288
   shr	   ecx, 2
1289
   and	   edx, 3
1290
   rep	   movsd
1291
   mov	   ecx, edx
1292
   rep	   movsb
261 hidnplayr 1293
   ;**************set length tag**************
1254 hidnplayr 1294
   mov	   ecx, [esp+12]		  ;restore packet size
1295
   and	   ecx, SIS900_DSIZE	 ;
1296
   inc	    [ebx+device.packets_tx]
1297
   add	    dword [ebx+device.bytes_tx], ecx
1298
   adc	    dword [ebx+device.bytes_tx+4], 0
261 hidnplayr 1299
   ;**************pad to minimum packet size **************not needed
1300
   ;cmp       ecx, SIS900_ETH_ZLEN
1301
   ;jge       SIS900_transmit_Size_Ok
1302
   ;push      ecx
1303
   ;mov       ebx, SIS900_ETH_ZLEN
1304
   ;sub       ebx, ecx
1305
   ;mov       ecx, ebx
1306
   ;rep       movsb
1307
   ;pop       ecx
1308
SIS900_transmit_Size_Ok:
1254 hidnplayr 1309
   or	    ecx, 0x80000000				;card owns descriptor
1310
   mov	    [ebx+device.txd+4], ecx
261 hidnplayr 1311
if defined SIS900_DEBUG
1254 hidnplayr 1312
   mov	    esi, SIS900_Debug_Transmit_Packet
261 hidnplayr 1313
   call     sys_msg_board_str
1314
end if
1315
   ;***************restart the transmitter ********
1254 hidnplayr 1316
   lea	    edx,[ebp+SIS900_cr]
1317
   in	    eax, dx			    ; Get current Command Register
1318
   or	    eax, SIS900_TxENA	; Enable Transmitter
1319
   out	    dx, eax
261 hidnplayr 1320
   ;****make sure packet transmitted successfully****
1321
;   mov      esi,10
1322
;   call     delay_ms
1254 hidnplayr 1323
   mov	    eax, [ebx+device.txd+4]
1324
   and	    eax, 0x6200000
1325
   jz	    SIS900_transmit_OK
261 hidnplayr 1326
   ;**************Tell user there was an error through debug window
1327
if defined SIS900_DEBUG
1254 hidnplayr 1328
   mov	    esi, SIS900_Debug_Transmit_Packet_Err
261 hidnplayr 1329
   call     sys_msg_board_str
1330
end if
1331
SIS900_transmit_OK:
1254 hidnplayr 1332
   pop	    ebp
1237 clevermous 1333
transmit_finish:
261 hidnplayr 1334
   ret
1335
 
1336
;***************************************************************************
1337
;* Function: Create_Mac_String
1338
;*
1339
;* Description: Converts the 48 bit value to a string for display
1340
;*
1341
;* String Format: XX:XX:XX:XX:XX:XX
1342
;*
1343
;* Arguments: node_addr is location of 48 bit MAC ID
1344
;*
1345
;* Returns:   Prints string to general debug window
1346
;*
1347
;*
1348
;done
1349
;***************************************************************************
1350
if defined SIS900_DEBUG
1351
 
1352
SIS900_Char_String    db '0','1','2','3','4','5','6','7','8','9'
1254 hidnplayr 1353
		      db 'A','B','C','D','E','F'
261 hidnplayr 1354
Mac_str_build: times 20 db 0
1355
Create_Mac_String:
1356
   pusha
1357
   xor ecx, ecx
1358
Create_Mac_String_loop:
1359
   mov al,byte [edx+ecx];[node_addr+ecx]
1360
   push eax
1361
   shr eax, 4
1362
   and eax, 0x0f
1363
   mov bl, byte [SIS900_Char_String+eax]
1364
   mov [Mac_str_build+ecx*3], bl
1365
   pop eax
1366
   and eax, 0x0f
1367
   mov bl, byte [SIS900_Char_String+eax]
1368
   mov [Mac_str_build+1+ecx*3], bl
1369
   cmp ecx, 5
1370
   je Create_Mac_String_done
1371
   mov bl, ':'
1372
   mov [Mac_str_build+2+ecx*3], bl
1373
   inc ecx
1374
   jmp Create_Mac_String_loop
1254 hidnplayr 1375
Create_Mac_String_done: 				;Insert CR and Zero Terminate
261 hidnplayr 1376
   mov [Mac_str_build+2+ecx*3],byte 13
1377
   mov [Mac_str_build+3+ecx*3],byte 10
1378
   mov [Mac_str_build+4+ecx*3],byte 0
1379
   mov esi, Mac_str_build
1254 hidnplayr 1380
   call sys_msg_board_str				;Print String to message board
261 hidnplayr 1381
   popa
1382
   ret
1383
end if
1384
;***************************************************************************
1385
;*      Set device to be a busmaster in case BIOS neglected to do so.
1386
;*      Also adjust PCI latency timer to a reasonable value, 64.
1387
;***************************************************************************
1388
SIS900_adjust_pci_device:
1389
   ;*******Get current setting************************
1237 clevermous 1390
   stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04
261 hidnplayr 1391
   ;******see if its already set as bus master********
1254 hidnplayr 1392
   mov	    cx, ax
1393
   and	    cx,5
1394
   cmp	    cx,5
1395
   je	    SIS900_adjust_pci_device_Latency
261 hidnplayr 1396
   ;******Make card a bus master*******
1254 hidnplayr 1397
   mov	    cx, ax				;value to write
1398
   or	    cx,5
1237 clevermous 1399
   stdcall PciWrite16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04, ecx
261 hidnplayr 1400
   ;******Check latency setting***********
1401
SIS900_adjust_pci_device_Latency:
1402
   ;*******Get current latency setting************************
1237 clevermous 1403
   stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D
261 hidnplayr 1404
   ;******see if its aat least 64 clocks********
1254 hidnplayr 1405
   cmp	    al,64
1406
   jge	    SIS900_adjust_pci_device_Done
261 hidnplayr 1407
   ;******Set latency to 32 clocks*******
1237 clevermous 1408
   stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D, 64
261 hidnplayr 1409
   ;******Check latency setting***********
1410
SIS900_adjust_pci_device_Done:
1411
   ret
1237 clevermous 1412
 
1413
; End of code
1414
 
1415
align 4 					; Place all initialised data here
1416
 
1417
NUM_DEV   dd 0
1418
 
1419
sis900_specific_table:
1420
;    dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0
1421
;    dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0
1422
    dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0
1423
    dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0
1424
    dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN
1425
    dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0
1426
    dd SIS900_960_REV,SIS960_get_mac_addr,0
1427
    dd SIS900B_900_REV,SIS900_get_mac_addr,0
1428
    dd 0,0,0,0 ; end of list
1429
 
1430
version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
1431
my_service    db 'SIS900',0			; max 16 chars include zero
1432
 
1433
include_debug_strings				; All data wich FDO uses will be included here
1434
 
1435
section '.data' data readable writable align 16 ; place all uninitialized data place here
1436
 
1254 hidnplayr 1437
DEV_LIST rd MAX_DEVICES 		; This list contains all pointers to device structures the driver is handling
1237 clevermous 1438