Subversion Repositories Kolibri OS

Rev

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