25,12 → 25,9 |
|
MAX_DEVICES = 16 |
|
RX_DES_COUNT = 4 ; no of RX descriptors, must be power of 2 |
RX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, must be multiple of 4 and <= 2048 TDES1_TBS1_MASK |
TX_RING_SIZE = 4 |
RX_RING_SIZE = 4 |
|
TX_DES_COUNT = 4 ; no of TX descriptors, must be power of 2 |
TX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, used for memory allocation only |
|
__DEBUG__ = 1 |
__DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only |
|
42,6 → 39,24 |
include '../fdo.inc' |
include '../netdrv.inc' |
|
; Capability flags used in chiplist |
FLAG_HAS_MII = 1 shl 0 |
FLAG_HAS_MEDIA_TABLE = 1 shl 1 |
FLAG_CSR12_IN_SROM = 1 shl 2 |
FLAG_ALWAYS_CHECK_MII = 1 shl 3 |
FLAG_HAS_ACPI = 1 shl 4 |
|
; Chip id's |
DC21040 = 0 |
DC21041 = 1 |
DC21140 = 2 |
DC21142 = 3 |
DC21143 = 3 |
LC82C168 = 4 |
MX98713 = 5 |
MX98715 = 6 |
MX98725 = 7 |
|
;------------------------------------------- |
; configuration registers |
;------------------------------------------- |
80,21 → 95,23 |
CSR0_DEFAULT = CSR0_WIE + CSR0_RLE + CSR0_RML + CSR0_CACHEALIGN_NONE |
|
;------- CSR5 -STATUS- bits -------------------------------- |
CSR5_TI = 1 shl 0 ; Transmit interupt - frame transmition completed |
CSR5_TPS = 1 shl 1 ; Transmit process stopped |
CSR5_TU = 1 shl 2 ; Transmit Buffer unavailable |
CSR5_TJT = 1 shl 3 ; Transmit Jabber Timeout (transmitter had been excessively active) |
CSR5_UNF = 1 shl 5 ; Transmit underflow - FIFO underflow |
CSR5_RI = 1 shl 6 ; Receive Interrupt |
CSR5_RU = 1 shl 7 ; Receive Buffer unavailable |
CSR5_RPS = 1 shl 8 ; Receive Process stopped |
CSR5_RWT = 1 shl 9 ; Receive Watchdow Timeout |
CSR5_ETI = 1 shl 10 ; Early transmit Interrupt |
CSR5_GTE = 1 shl 11 ; General Purpose Timer Expired |
CSR5_FBE = 1 shl 13 ; Fatal bus error |
CSR5_ERI = 1 shl 14 ; Early receive Interrupt |
CSR5_AIS = 1 shl 15 ; Abnormal interrupt summary |
CSR5_NIS = 1 shl 16 ; normal interrupt summary |
CSR5_TI = 0x00000001 ;1 shl 0 ; Transmit interupt - frame transmition completed |
CSR5_TPS = 0x00000002 ;1 shl 1 ; Transmit process stopped |
CSR5_TU = 0x00000004 ;1 shl 2 ; Transmit Buffer unavailable |
CSR5_TJT = 0x00000008 ;1 shl 3 ; Transmit Jabber Timeout (transmitter had been excessively active) |
CSR5_LP = 0x00000010 ;1 shl 4 ; Link pass |
CSR5_UNF = 0x00000020 ;1 shl 5 ; Transmit underflow - FIFO underflow |
CSR5_RI = 0x00000040 ;1 shl 6 ; Receive Interrupt |
CSR5_RU = 0x00000080 ;1 shl 7 ; Receive Buffer unavailable |
CSR5_RPS = 0x00000100 ;1 shl 8 ; Receive Process stopped |
CSR5_RWT = 0x00000200 ;1 shl 9 ; Receive Watchdow Timeout |
CSR5_ETI = 0x00000400 ;1 shl 10 ; Early transmit Interrupt |
CSR5_GTE = 0x00000800 ;1 shl 11 ; General Purpose Timer Expired |
CSR5_LF = 0x00001000 ;1 shl 12 ; Link Fail |
CSR5_FBE = 0x00002000 ;1 shl 13 ; Fatal bus error |
CSR5_ERI = 0x00004000 ;1 shl 14 ; Early receive Interrupt |
CSR5_AIS = 0x00008000 ;1 shl 15 ; Abnormal interrupt summary |
CSR5_NIS = 0x00010000 ;1 shl 16 ; normal interrupt summary |
CSR5_RS_SH = 17 ; Receive process state -shift |
CSR5_RS_MASK = 111b ; -mask |
CSR5_TS_SH = 20 ; Transmit process state -shift |
118,7 → 135,7 |
CSR6_PB = 1 shl 3 ; Pass bad frames |
CSR6_IF = 1 shl 4 ; Inverse filtering |
CSR6_SB = 1 shl 5 ; Start/Stop backoff counter |
CSR6_PR = 1 shl 6 ; Promiscuos mode -default after reset |
CSR6_PR = 1 shl 6 ; Promiscuous mode -default after reset |
CSR6_PM = 1 shl 7 ; Pass all multicast |
CSR6_F = 1 shl 9 ; Full Duplex mode |
CSR6_OM_SH = 10 ; Operating Mode -shift |
217,35 → 234,46 |
TDES1_LS = 1 shl 30 ; Last segment |
TDES1_IC = 1 shl 31 ; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1 |
|
RX_MEM_TOTAL_SIZE = RX_DES_COUNT*(sizeof.DES+RX_BUFF_SIZE) |
TX_MEM_TOTAL_SIZE = TX_DES_COUNT*(sizeof.DES+TX_BUFF_SIZE) |
FULL_DUPLEX_MAGIC = 0x6969 |
;MAX_ETH_FRAME_SIZE = 1514 |
|
|
struct device ETH_DEVICE |
|
rx_p_des dd ? ; descriptors ring with received packets |
tx_p_des dd ? ; descriptors ring with 'to transmit' packets |
tx_free_des dd ? ; Tx descriptors available |
tx_wr_des dd ? ; Tx current descriptor to write data to |
tx_rd_des dd ? ; Tx current descriptor to read TX completion |
rx_crt_des dd ? ; Rx current descriptor |
|
io_addr dd ? |
pci_bus dd ? |
pci_dev dd ? |
irq_line db ? |
rb 3 ; alignment |
|
id dd ? ; identification number |
io_size dd ? |
flags dd ? |
csr6 dd ? |
csr7 dd ? |
if_port dd ? |
saved_if_port dd ? |
default_port dd ? |
mtable dd ? |
mii_cnt dd ? |
|
cur_rx dd ? |
cur_tx dd ? ; Tx current descriptor to write data to |
last_tx dd ? ; Tx current descriptor to read TX completion |
|
rb 0x100-($ and 0xff) ; align 256 |
rx_ring rb RX_RING_SIZE*2*sizeof.desc |
|
rb 0x100-($ and 0xff) ; align 256 |
tx_ring rb TX_RING_SIZE*2*sizeof.desc |
|
ends |
|
;----------- descriptor structure --------------------- |
struct DES |
struct desc |
status dd ? ; bit 31 is 'own' and rest is 'status' |
length dd ? ; control bits + bytes-count buffer 1 + bytes-count buffer 2 |
buffer1 dd ? ; pointer to buffer1 |
buffer2 dd ? ; pointer to buffer2 or in this case to next descriptor, as we use a chained structure |
virtaddr dd ? |
|
rb 0x40 - ($ and 0x3f) ; align 64 |
buffer2 dd ? ; pointer to buffer2 |
ends |
|
;============================================================================= |
380,15 → 408,9 |
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
jae .fail |
|
push edx |
invoke KernelAlloc, sizeof.device ; Allocate the buffer for eth_device structure |
pop edx |
test eax, eax |
jz .fail |
mov ebx, eax ; ebx is always used as a pointer to the structure (in driver, but also in kernel code) |
allocate_and_clear ebx, sizeof.device, .fail |
|
; Fill in the direct call addresses into the struct |
|
mov [ebx + device.reset], reset |
mov [ebx + device.transmit], transmit |
mov [ebx + device.unload], unload |
395,7 → 417,6 |
mov [ebx + device.name], my_service |
|
; save the pci bus and device numbers |
|
mov eax, [edx + IOCTL.input] |
movzx ecx, byte[eax+1] |
mov [ebx + device.pci_bus], ecx |
403,12 → 424,10 |
mov [ebx + device.pci_dev], ecx |
|
; Now, it's time to find the base io addres of the PCI device |
|
stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev] |
mov [ebx + device.io_addr], eax |
|
; We've found the io address, find IRQ now |
|
invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line |
mov [ebx + device.irq_line], al |
|
415,9 → 434,6 |
DEBUGF 2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ |
[ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8 |
|
allocate_and_clear [ebx + device.rx_p_des], RX_DES_COUNT*(sizeof.DES+RX_BUFF_SIZE), .err |
allocate_and_clear [ebx + device.tx_p_des], TX_DES_COUNT*(sizeof.DES+TX_BUFF_SIZE), .err |
|
; Ok, the eth_device structure is ready, let's probe the device |
; Because initialization fires IRQ, IRQ handler must be aware of this device |
mov eax, [devices] ; Add the device structure to our device list |
428,7 → 444,6 |
test eax, eax |
jnz .err2 ; If an error occured, exit |
|
|
mov [ebx + device.type], NET_TYPE_ETH |
invoke NetRegDev |
|
456,11 → 471,8 |
dec [devices] |
.err: |
DEBUGF 2,"removing device structure\n" |
invoke KernelFree, [ebx + device.rx_p_des] |
invoke KernelFree, [ebx + device.tx_p_des] |
invoke KernelFree, ebx |
|
|
.fail: |
or eax, -1 |
ret |
483,22 → 495,13 |
; |
; - Stop the device |
; - Detach int handler |
; - Remove device from local list (RTL8139_LIST) |
; - Remove device from local list |
; - call unregister function in kernel |
; - Remove all allocated structures and buffers the card used |
|
or eax,-1 |
|
ret |
|
|
macro status { |
set_io [ebx + device.io_addr], CSR5 |
in eax, dx |
DEBUGF 1,"CSR5: %x\n", eax |
} |
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Probe ;; |
508,57 → 511,46 |
align 4 |
probe: |
|
DEBUGF 2,"Probing dec21x4x device: " |
DEBUGF 2,"Probing\n" |
|
; Make the device a bus master |
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command |
or al, PCI_CMD_MASTER |
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax |
|
; Check the vendor/device ID |
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0 ; get device/vendor id |
DEBUGF 1,"Vendor id: 0x%x\n", ax |
mov esi, chiplist |
.loop: |
cmp dword[esi], eax |
je .got_it |
add esi, 6*4 |
cmp dword[esi], 0 |
jne .loop |
DEBUGF 2, "Unknown chip: 0x%x aborting\n", eax |
|
cmp ax, 0x1011 |
je .dec |
cmp ax, 0x1317 |
je .admtek |
jmp .notfound |
|
.dec: |
shr eax, 16 |
DEBUGF 1,"Vendor ok!, device id: 0x%x\n", ax ; TODO: use another method to detect chip! |
|
cmp ax, 0x0009 |
je .supported_device |
|
cmp ax, 0x0019 |
je .supported_device2 |
|
.admtek: |
shr eax, 16 |
DEBUGF 1,"Vendor ok!, device id: 0x%x\n", ax |
|
cmp ax, 0x0985 |
je .supported_device |
|
.notfound: |
DEBUGF 1,"Device not supported!\n" |
or eax, -1 |
ret |
|
.supported_device2: |
.got_it: |
lodsd |
lodsd |
mov [ebx + device.id], eax |
lodsd |
mov [ebx + device.io_size], eax |
lodsd |
mov [ebx + device.csr7], eax |
lodsd |
mov [ebx + device.name], eax |
DEBUGF 1, "Detected chip = %s\n", eax |
lodsd |
mov [ebx + device.flags], eax |
|
; wake up the 21143 |
; PROBE1 |
|
test [ebx + device.flags], FLAG_HAS_ACPI |
jz .no_acpi |
DEBUGF 1, "Device has ACPI capabilities, time to wake it up\n" |
xor eax, eax |
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, eax |
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, eax ; wake up the 21143 |
.no_acpi: |
|
call SROM_GetWidth ; TODO: use this value returned in ecx in the read_word routine! |
|
.supported_device: |
call SROM_GetWidth ; TODO: use this value returned in ecx |
; in the read_word routine! |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Reset ;; |
568,33 → 560,124 |
align 4 |
reset: |
|
DEBUGF 2,"Resetting dec21x4x\n" |
DEBUGF 2,"Reset\n" |
|
;----------------------------------------------------------- |
; board software reset - if fails, dont do nothing else |
; Make the device a bus master |
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command |
or al, PCI_CMD_MASTER |
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax |
|
; Stop TX and RX |
set_io [ebx + device.io_addr], 0 |
status |
set_io [ebx + device.io_addr], CSR0 |
mov eax, CSR0_RESET |
set_io [ebx + device.io_addr], CSR6 |
in eax, dx |
and eax, not (CSR6_ST or CSR6_SR) |
out dx, eax |
|
; wait at least 50 PCI cycles |
mov esi, 1000 |
invoke Sleep |
; Clear missed packet counter |
set_io [ebx + device.io_addr], CSR8 |
in eax, dx |
|
;----------- |
; setup CSR0 |
;; wait at least 50 PCI cycles |
; mov esi, 1000 |
; invoke Sleep |
|
cmp [ebx + device.id], DC21041 |
jne @f |
; set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR9 |
in eax, dx |
test eax, 0x8000 |
jz @f |
DEBUGF 1, "21040 compatibility mode\n" |
mov [ebx + device.id], DC21040 |
@@: |
|
|
;;; Find connected mii xceivers? 993-1043 |
|
; Reset the xcvr interface and turn on heartbeat. |
cmp [ebx + device.id], DC21041 |
jne @f |
set_io [ebx + device.io_addr], 0 |
status |
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
out dx, eax |
set_io [ebx + device.io_addr], CSR14 |
dec eax |
out dx, eax |
set_io [ebx + device.io_addr], CSR15 |
inc eax |
mov al, 8 |
out dx, eax |
set_io [ebx + device.io_addr], CSR6 |
in eax, dx |
or ax, CSR6_ST |
out dx, eax |
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
mov ax, 0xEF05 |
out dx, eax |
jmp .reset_done |
@@: |
cmp [ebx + device.id], DC21040 |
jne @f |
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
out dx, eax |
mov al, 4 |
out dx, eax |
jmp .reset_done |
@@: |
cmp [ebx + device.id], DC21140 |
jne @f |
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR12 |
mov eax, 0x100 |
out dx, eax |
jmp .reset_done |
@@: |
cmp [ebx + device.id], DC21142 |
jne @f |
; if tp->mii_cnt |
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR6 |
mov eax, 0x82020000 |
out dx, eax |
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
out dx, eax |
set_io [ebx + device.io_addr], CSR14 |
out dx, eax |
set_io [ebx + device.io_addr], CSR6 |
mov eax, 0x820E0000 |
out dx, eax |
jmp .reset_done |
;;;; TODO |
@@: |
cmp [ebx + device.id], LC82C168 |
jne @f |
; TODO |
@@: |
cmp [ebx + device.id], MX98713 |
jne @f |
; TODO |
@@: |
|
.reset_done: |
|
|
; OPEN |
|
; Reset chip |
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR0 |
mov eax, CSR0_DEFAULT |
mov eax, CSR0_RESET |
out dx, eax |
|
|
; wait at least 50 PCI cycles |
mov esi, 1000 |
mov esi, 100 |
invoke Sleep |
|
;----------------------------------- |
615,69 → 698,142 |
ret |
@@: |
|
;---------------- |
; Set cache modes |
|
set_io [ebx + device.io_addr], 0 |
status |
set_io [ebx + device.io_addr], CSR0 |
mov eax, 0x01A00000 or 0x4800 ; CSR0_DEFAULT |
out dx, eax |
|
; wait at least 50 PCI cycles |
mov esi, 100 |
invoke Sleep |
|
;--------------------------- |
; Initialize RX and TX rings |
|
call init_ring |
test eax, eax |
jnz .err |
|
;------------------- |
; Set receive filter |
|
call create_setup_frame |
|
;-------------------------------------------- |
; setup CSR3 & CSR4 (pointers to descriptors) |
|
lea eax, [ebx + device.rx_ring] |
invoke GetPhysAddr |
DEBUGF 1,"RX descriptor base address: %x\n", eax |
set_io [ebx + device.io_addr], 0 |
status |
set_io [ebx + device.io_addr], CSR3 |
mov eax, [ebx + device.rx_p_des] |
invoke GetPhysAddr |
DEBUGF 1,"RX descriptor base address: %x\n", eax |
out dx, eax |
|
set_io [ebx + device.io_addr], CSR4 |
mov eax, [ebx + device.tx_p_des] |
lea eax, [ebx + device.tx_ring] |
invoke GetPhysAddr |
DEBUGF 1,"TX descriptor base address: %x\n", eax |
set_io [ebx + device.io_addr], CSR4 |
out dx, eax |
|
;------------------------------------------------------- |
; setup interrupt mask register -expect IRQs from now on |
; Select media |
push [ebx + device.if_port] |
pop [ebx + device.saved_if_port] |
cmp [ebx + device.if_port], 0 |
jne @f |
push [ebx + device.default_port] |
pop [ebx + device.if_port] |
@@: |
cmp [ebx + device.id], DC21041 |
jne @f |
cmp [ebx + device.if_port], 4 |
jbe @f |
; invalid port, select inital TP, autosense, autonegotiate |
mov [ebx + device.if_port], 4 ; CHECKME |
@@: |
|
status |
DEBUGF 1,"Enabling interrupts\n" |
set_io [ebx + device.io_addr], CSR7 |
mov eax, CSR7_DEFAULT |
out dx, eax |
status |
; Allow selecting a default media |
cmp [ebx + device.mtable], 0 |
je .media_picked |
|
;---------- |
; enable RX |
cmp [ebx + device.if_port], 0 |
je @f |
;; TODO |
jmp .media_picked |
@@: |
|
.media_picked: |
mov [ebx + device.csr6], 0 |
|
cmp [ebx + device.id], DC21142 |
jne @f |
cmp [ebx + device.if_port], 0 |
jne @f |
;; TODO |
mov [ebx + device.csr6], 0x82420200 |
mov [ebx + device.if_port], 11 |
set_io [ebx + device.io_addr], 0 |
status |
DEBUGF 1,"Enable RX\n" |
set_io [ebx + device.io_addr], CSR14 |
mov eax, 0x0003FFF |
out dx, eax |
set_io [ebx + device.io_addr], CSR15 |
xor eax, eax |
mov al, 8 |
out dx, eax |
set_io [ebx + device.io_addr], CSR13 |
mov al, 1 |
out dx, eax |
set_io [ebx + device.io_addr], CSR12 |
mov ax, 0x1301 |
out dx, eax |
|
set_io [ebx + device.io_addr], CSR6 |
Bit_Set CSR6_SR; or CSR6_PR or CSR6_ST |
DEBUGF 1,"CSR6: %x\n", eax |
@@: |
cmp [ebx + device.id], LC82C168 |
jne @f |
;; TODO |
@@: |
cmp [ebx + device.id], MX98713 |
jne @f |
|
status |
@@: |
;; wait a bit |
; mov esi, 500 |
; invoke Sleep |
|
call start_link |
; else: |
xor eax, eax |
inc eax |
call select_media |
|
; wait a bit |
mov esi, 500 |
invoke Sleep |
; Start the chip's tx to process setup frame |
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR6 |
mov eax, [ebx + device.csr6] |
out dx, eax |
or ax, CSR6_ST |
out dx, eax |
|
;---------------------------------------------------- |
; send setup packet to notify the board about the MAC |
; Enable interrupts by setting the interrupt mask. |
set_io [ebx + device.io_addr], CSR5 |
mov eax, [ebx + device.csr7] |
DEBUGF 1, "Setting CSR7 to 0x%x\n", eax |
out dx, eax |
set_io [ebx + device.io_addr], CSR7 |
out dx, eax |
|
call Send_Setup_Packet |
; Enable receiver |
set_io [ebx + device.io_addr], CSR6 |
mov eax, [ebx + device.csr6] |
or eax, 0x2002 + CSR6_RA |
out dx, eax |
|
; RX poll demand |
set_io [ebx + device.io_addr], CSR2 |
xor eax, eax |
; clear packet/byte counters |
out dx, eax |
|
lea edi, [ebx + device.bytes_tx] |
mov ecx, 6 |
rep stosd |
|
; Set the mtu, kernel will be able to send now |
mov [ebx + device.mtu], 1514 |
|
684,8 → 840,13 |
; Set link state to unknown |
mov [ebx + device.state], ETH_LINK_UNKNOWN |
|
DEBUGF 1,"Reset done\n" |
DEBUGF 1,"Reset completed\n" |
; xor eax, eax |
ret |
|
.err: |
DEBUGF 2,"Reset failed\n" |
or eax, -1 |
ret |
|
|
693,80 → 854,176 |
align 4 |
init_ring: |
|
;------------------------------------------ |
; Setup RX descriptors (use chained method) |
DEBUGF 1,"Init ring\n" |
|
mov eax, [ebx + device.rx_p_des] |
;--------------------- |
; Setup RX descriptors |
|
lea eax, [ebx + device.rx_ring] |
invoke GetPhysAddr |
mov edx, eax |
push eax |
lea esi, [eax + RX_DES_COUNT*(sizeof.DES)] ; jump over RX descriptors |
mov eax, [ebx + device.rx_p_des] |
add eax, RX_DES_COUNT*(sizeof.DES) ; jump over RX descriptors |
mov edi, [ebx + device.rx_p_des] |
mov ecx, RX_DES_COUNT |
lea edi, [ebx + device.rx_ring] |
mov ecx, RX_RING_SIZE |
.loop_rx_des: |
add edx, sizeof.DES |
mov [edi + DES.status], DES0_OWN ; hardware owns buffer |
mov [edi + DES.length], 1984 + RDES1_RCH ; only size of first buffer, chained buffers |
mov [edi + DES.buffer1], esi ; hw buffer address |
mov [edi + DES.buffer2], edx ; pointer to next descriptor |
mov [edi + DES.virtaddr], eax ; virtual buffer address |
DEBUGF 1,"RX desc: buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", esi, edx, eax, edi |
|
add esi, RX_BUFF_SIZE |
add eax, RX_BUFF_SIZE |
add edi, sizeof.DES |
DEBUGF 1,"RX descriptor 0x%x\n", edi |
add edx, sizeof.desc |
mov [edi + desc.status], DES0_OWN |
mov [edi + desc.length], 1536 |
push edx edi ecx |
invoke KernelAlloc, 1536 |
pop ecx edi edx |
test eax, eax |
jz .out_of_mem |
mov [edi + RX_RING_SIZE*sizeof.desc], eax |
invoke GetPhysAddr |
mov [edi + desc.buffer1], eax |
mov [edi + desc.buffer2], edx |
add edi, sizeof.desc |
dec ecx |
jnz .loop_rx_des |
|
; set last descriptor as LAST |
or [edi - sizeof.DES + DES.length], RDES1_RER ; EndOfRing |
pop [edi - sizeof.DES + DES.buffer2] ; point it to the first descriptor |
or [edi - sizeof.desc + desc.length], RDES1_RER ; EndOfRing |
pop [edi - sizeof.desc + desc.buffer2] ; point it to the first descriptor |
|
;--------------------- |
; Setup TX descriptors |
|
mov eax, [ebx + device.tx_p_des] |
lea eax, [ebx + device.tx_ring] |
invoke GetPhysAddr |
mov edx, eax |
push eax |
lea esi, [eax + TX_DES_COUNT*(sizeof.DES)] ; jump over TX descriptors |
mov eax, [ebx + device.tx_p_des] |
add eax, TX_DES_COUNT*(sizeof.DES) ; jump over TX descriptors |
mov edi, [ebx + device.tx_p_des] |
mov ecx, TX_DES_COUNT |
lea edi, [ebx + device.tx_ring] |
mov ecx, TX_RING_SIZE |
.loop_tx_des: |
add edx, sizeof.DES |
mov [edi + DES.status], 0 ; owned by driver |
mov [edi + DES.length], TDES1_TCH ; chained method |
mov [edi + DES.buffer1], esi ; pointer to buffer |
mov [edi + DES.buffer2], edx ; pointer to next descr |
mov [edi + DES.virtaddr], eax |
DEBUGF 1,"TX desc: buff addr: %x, next desc: %x, virt buff addr: %x, virt descr addr: %x \n", esi, edx, eax, edi |
|
add esi, TX_BUFF_SIZE |
add eax, TX_BUFF_SIZE |
add edi, sizeof.DES |
DEBUGF 1,"TX descriptor 0x%x\n", edi |
add edx, sizeof.desc |
mov [edi + desc.status], 0 ; owned by driver |
mov [edi + desc.length], 0 |
mov [edi + desc.buffer1], 0 |
mov [edi + desc.buffer2], edx ; pointer to next descr |
add edi, sizeof.desc |
dec ecx |
jnz .loop_tx_des |
|
; set last descriptor as LAST |
or [edi - sizeof.DES + DES.length], TDES1_TER ; EndOfRing |
pop [edi - sizeof.DES + DES.buffer2] ; point it to the first descriptor |
or [edi - sizeof.desc + desc.length], TDES1_TER ; EndOfRing |
pop [edi - sizeof.desc + desc.buffer2] ; point it to the first descriptor |
|
;------------------ |
; Reset descriptors |
|
mov [ebx + device.tx_wr_des], 0 |
mov [ebx + device.tx_rd_des], 0 |
mov [ebx + device.rx_crt_des], 0 |
mov [ebx + device.tx_free_des], TX_DES_COUNT |
xor eax, eax |
mov [ebx + device.cur_tx], eax |
mov [ebx + device.last_tx], eax |
mov [ebx + device.cur_rx], eax |
|
ret |
|
.out_of_mem: |
DEBUGF 2, "Out of memory!\n" |
pop eax |
or eax, -1 |
ret |
|
|
; IN: eax = startup |
align 4 |
select_media: |
|
DEBUGF 1, "Selecting media\n" |
|
cmp [ebx + device.mtable], 0 |
je .no_mtable |
DEBUGF 1, "Device has a media table\n" |
|
|
; default: |
mov eax, 0x020E0000 |
jmp .update_csr6 |
|
.no_mtable: |
DEBUGF 1, "Device has no media table\n" |
|
cmp [ebx + device.id], DC21041 |
jne .not_41 |
DEBUGF 1, "DC21041\n" |
|
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
out dx, eax ; reset serial interface |
set_io [ebx + device.io_addr], CSR14 |
mov eax, 0x7F3F ;0x7F3F ;0x7F3D ; 10T-FD |
out dx, eax |
set_io [ebx + device.io_addr], CSR15 |
mov eax, 0x0008 ;0x0008 ;0x0008 ; 10T-FD |
out dx, eax |
set_io [ebx + device.io_addr], CSR13 |
mov eax, 0xEF05 ;0xEF01 ;0xEF09 ; 10T-FD |
out dx, eax |
mov eax, 0x80020000 |
jmp .update_csr6 |
.not_41: |
cmp [ebx + device.id], LC82C168 |
jne .not_LC |
DEBUGF 1, "LC82C168\n" |
|
;; TODO |
|
mov eax, 0x812C0000 |
jmp .update_csr6 |
.not_LC: |
cmp [ebx + device.id], DC21040 |
jne .not_40 |
DEBUGF 1, "DC21040\n" |
|
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR11 |
mov eax, FULL_DUPLEX_MAGIC |
out dx, eax |
; reset serial interface |
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
out dx, eax |
|
set_io [ebx + device.io_addr], CSR13 |
xor eax, eax |
cmp [ebx + device.if_port], 0 |
je @f |
mov al, 0xc |
out dx, eax |
mov eax, 0x01860000 |
jmp .update_csr6 |
@@: |
mov al, 4 |
out dx, eax |
mov eax, 0x00420000 |
jmp .update_csr6 |
|
.not_40: |
DEBUGF 1, "Unkown chip with no media table\n" |
|
cmp [ebx + device.default_port], 0 |
jne .not_0 |
cmp [ebx + device.mii_cnt], 0 |
je @f |
mov [ebx + device.if_port], 11 |
jmp .not_0 |
@@: |
mov [ebx + device.if_port], 3 |
.not_0: |
mov eax, 0x020E0000 ;;;;; |
|
.update_csr6: |
and [ebx + device.csr6], 0xfdff |
or ax, 0x0200 ;; FULL DUPLEX |
or [ebx + device.csr6], eax |
DEBUGF 1, "new CSR6: 0x%x\n", [ebx + device.csr6] |
|
ret |
|
|
align 4 |
start_link: |
|
DEBUGF 1,"Starting link\n" |
782,125 → 1039,50 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
align 4 |
Send_Setup_Packet: |
create_setup_frame: |
|
DEBUGF 1,"Sending setup packet\n" |
DEBUGF 1,"Creating setup packet\n" |
|
; if no descriptors available, out |
mov ecx, 1000 |
@@loop_wait_desc: |
cmp [ebx + device.tx_free_des], 0 |
jne @f |
invoke KernelAlloc, 192 |
test eax, eax |
jz .err |
|
dec ecx |
jnz @@loop_wait_desc |
push eax |
|
mov eax, -1 |
ret |
@@: |
mov edi, eax |
xor eax, eax |
dec ax |
stosd |
stosd |
stosd |
|
; go to current send descriptor |
mov edi, [ebx + device.tx_p_des] |
mov eax, [ebx + device.tx_wr_des] |
DEBUGF 1,"Got free descriptor: %u (%x)", eax, edi |
mov edx, sizeof.DES |
mul edx |
add edi, eax |
DEBUGF 1,"=>%x\n", edi |
|
; if NOT sending FIRST setup packet, must set current descriptor to 0 size for both buffers, |
; and go to next descriptor for real setup packet... ;; TODO: check if 2 descriptors are available |
|
; cmp [ebx + device.tx_packets], 0 |
; je .first |
; |
; and [edi+DES.des1], 0 |
; mov [edi+DES.des0], DES0_OWN |
; |
; go to next descriptor |
; inc [ebx + device.tx_wr_des] |
; and [ebx + device.tx_wr_des], TX_DES_COUNT-1 |
; |
; dec free descriptors count |
; cmp [ebx + device.tx_free_des], 0 |
; jz @f |
; dec [ebx + device.tx_free_des] |
; @@: |
; |
; ; recompute pointer to current descriptor |
; mov edi, [ebx + device.tx_p_des] |
; mov eax, [ebx + device.tx_wr_des] |
; mov edx, DES.size |
; mul edx |
; add edi, eax |
|
.first: |
|
push edi |
; copy setup packet to current descriptor |
mov edi, [edi + DES.virtaddr] |
; copy the address once |
mov ecx, 15 |
.loop: |
lea esi, [ebx + device.mac] |
DEBUGF 1,"copying packet to %x from %x\n", edi, esi |
mov ecx, 3 ; mac is 6 bytes thus 3 words |
.loop: |
DEBUGF 1,"%x ", [esi]:4 |
movsw |
inc edi |
inc edi |
lodsw |
stosd |
dec ecx |
jnz .loop |
|
DEBUGF 1,"\n" |
pop eax |
|
; copy 15 times the broadcast address |
mov ecx, 3*15 |
mov eax, 0xffffffff |
rep stosd |
|
pop edi |
|
; setup descriptor |
DEBUGF 1,"setting up descriptor\n" |
mov [edi + DES.length], TDES1_IC + TDES1_SET + TDES1_TCH + 192 ; size must be EXACTLY 192 bytes |
mov [edi + DES.status], DES0_OWN |
lea edi, [ebx + device.tx_ring] |
DEBUGF 1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi |
mov [edi + TX_RING_SIZE*sizeof.desc], eax |
invoke GetPhysAddr |
mov [edi + desc.buffer1], eax |
mov [edi + desc.length], TDES1_SET + 192 ; size must be EXACTLY 192 bytes + TDES1_IC |
mov [edi + desc.status], DES0_OWN |
DEBUGF 1, "descriptor 0x%x\n", edi |
|
DEBUGF 1,"status: %x\n", [edi + DES.status]:8 |
DEBUGF 1,"length: %x\n", [edi + DES.length]:8 |
DEBUGF 1,"buffer1: %x\n", [edi + DES.buffer1]:8 |
DEBUGF 1,"buffer2: %x\n", [edi + DES.buffer2]:8 |
|
; go to next descriptor |
inc [ebx + device.tx_wr_des] |
and [ebx + device.tx_wr_des], TX_DES_COUNT-1 |
inc [ebx + device.cur_tx] |
|
; dec free descriptors count |
cmp [ebx + device.tx_free_des], 0 |
jz @f |
dec [ebx + device.tx_free_des] |
@@: |
ret |
|
; start tx |
set_io [ebx + device.io_addr], 0 |
status |
set_io [ebx + device.io_addr], CSR6 |
in eax, dx |
test eax, CSR6_ST ; if NOT started, start now |
jnz .already_started |
or eax, CSR6_ST |
DEBUGF 1,"Starting TX\n" |
jmp .do_it |
.already_started: |
; if already started, issue a Transmit Poll command |
set_io [ebx + device.io_addr], CSR1 |
xor eax, eax |
DEBUGF 1,"Issuing transmit poll command\n" |
.do_it: |
out dx, eax |
status |
|
DEBUGF 1,"Sending setup packet, completed!\n" |
|
.err: |
DEBUGF 2, "Out of memory!\n" |
ret |
|
|
929,46 → 1111,45 |
|
cmp [buffersize], 1514 |
ja .fail |
cmp [buffersize], 60 |
jb .fail |
|
;-------------------------- |
; copy packet to crt buffer |
|
mov eax, [ebx + device.tx_wr_des] |
mov edx, sizeof.DES |
mov eax, [ebx + device.cur_tx] |
mov edx, sizeof.desc |
mul edx |
add eax, [ebx + device.tx_p_des] |
mov edi, [eax + DES.virtaddr] ; pointer to buffer |
mov esi, [bufferptr] |
mov ecx, [buffersize] |
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi |
rep movsb |
lea esi, [ebx + device.tx_ring + eax] |
test [esi + desc.status], DES0_OWN |
jnz .fail |
|
DEBUGF 1, "Descriptor is free\n" |
|
mov eax, [bufferptr] |
mov [esi + TX_RING_SIZE*sizeof.desc], eax |
invoke GetPhysAddr |
mov [esi + desc.buffer1], eax |
|
; set packet size |
mov ecx, [eax+DES.length] |
and ecx, TDES1_TER ; preserve 'End of Ring' bit |
or ecx, [buffersize] ; set size |
or ecx, TDES1_FS or TDES1_LS or TDES1_IC or TDES1_TCH ; first descr, last descr, interrupt on complete, chained modus |
mov [eax + DES.length], ecx |
mov eax, [esi + desc.length] |
and eax, TDES1_TER ; preserve 'End of Ring' bit |
or eax, [buffersize] ; set size |
or eax, TDES1_FS or TDES1_LS or TDES1_IC ; first descr, last descr, interrupt on complete |
mov [esi + desc.length], eax |
|
; set descriptor info |
mov [eax + DES.status], DES0_OWN ; say it is now owned by the 21x4x |
; set descriptor status |
mov [esi + desc.status], DES0_OWN ; say it is now owned by the 21x4x |
|
; start tx |
; Check if transmitter is running |
set_io [ebx + device.io_addr], 0 |
status |
set_io [ebx + device.io_addr], CSR6 |
in eax, dx |
test eax, CSR6_ST ; if NOT started, start now |
jnz .already_started |
or eax, CSR6_ST |
DEBUGF 1,"Starting TX\n" |
DEBUGF 1,"(Re) starting TX\n" |
jmp .do_it |
.already_started: |
; if already started, issues a Transmit Poll command |
|
; Trigger immediate transmit demand |
set_io [ebx + device.io_addr], CSR1 |
mov eax, -1 |
xor eax, eax |
.do_it: |
out dx , eax |
|
979,24 → 1160,16 |
adc dword [ebx + device.bytes_tx + 4], 0 |
|
; go to next descriptor |
inc [ebx + device.tx_wr_des] |
and [ebx + device.tx_wr_des], TX_DES_COUNT-1 |
inc [ebx + device.cur_tx] |
and [ebx + device.cur_tx], TX_RING_SIZE-1 |
|
; dec free descriptors count |
test [ebx + device.tx_free_des], -1 |
jz .end |
dec [ebx + device.tx_free_des] |
.end: |
status |
|
DEBUGF 1,"transmit ok\n" |
invoke KernelFree, [bufferptr] |
DEBUGF 1,"Transmit ok\n" |
popf |
xor eax, eax |
ret |
|
.fail: |
DEBUGF 1,"transmit failed\n" |
DEBUGF 2,"Transmit failed\n" |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
1015,7 → 1188,7 |
|
push ebx esi edi |
|
DEBUGF 1,"\n%s int\n", my_service |
DEBUGF 1,"INT\n" |
|
; find pointer of device wich made IRQ occur |
|
1028,9 → 1201,9 |
|
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR5 |
in ax, dx |
test ax, ax |
out dx, ax ; send it back to ACK |
in eax, dx |
and eax, 0x0001ffff |
out dx, eax ; send it back to ACK |
jnz .got_it |
.continue: |
add esi, 4 |
1043,73 → 1216,47 |
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
|
.got_it: |
DEBUGF 1,"Device: %x CSR5: %x\n", ebx, eax |
|
DEBUGF 1,"Device: %x CSR5: %x ", ebx, ax |
|
;---------------------------------- |
; TX ok? |
|
test ax, CSR5_TI |
test eax, CSR5_TI |
jz .not_tx |
push ax esi ecx |
|
push eax esi ecx |
DEBUGF 1,"TX ok!\n" |
|
; go to current descriptor |
mov edi, [ebx + device.tx_p_des] |
|
mov eax, [ebx + device.tx_rd_des] |
mov edx, sizeof.DES |
.loop_tx: |
; go to last descriptor |
mov eax, [ebx + device.last_tx] |
mov edx, sizeof.desc |
mul edx |
add edi, eax |
lea eax, [ebx + device.tx_ring + eax] |
|
.loop_tx: |
|
; done if all desc are free |
cmp [ebx + device.tx_free_des], TX_DES_COUNT |
jz .end_tx |
|
mov eax, [edi + DES.status] |
|
; we stop at first desc that is owned be NIC |
test eax, DES0_OWN |
DEBUGF 1,"descriptor 0x%x\n", eax |
test [eax + desc.status], DES0_OWN ; owned by the card? |
jnz .end_tx |
cmp [eax + desc.buffer1], 0 ; empty descriptor? |
je .end_tx |
|
; detect is setup packet |
cmp eax, (0ffffffffh - DES0_OWN) ; all other bits are 1 |
jne .not_setup_packet |
DEBUGF 1,"Setup Packet detected\n" |
.not_setup_packet: |
mov [eax + desc.buffer1], 0 |
DEBUGF 1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc] |
invoke KernelFree, [eax + TX_RING_SIZE*sizeof.desc] |
|
DEBUGF 1,"packet status: %x\n", eax |
|
; next descriptor |
add edi, sizeof.DES |
inc [ebx + device.tx_rd_des] |
and [ebx + device.tx_rd_des], TX_DES_COUNT-1 |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], TX_RING_SIZE-1 |
|
; inc free desc |
inc [ebx + device.tx_free_des] |
cmp [ebx + device.tx_free_des], TX_DES_COUNT |
jbe @f |
mov [ebx + device.tx_free_des], TX_DES_COUNT |
@@: |
|
jmp .loop_tx |
.end_tx: |
pop ecx esi eax |
.not_tx: |
|
;------------------------------------------------------ |
; here must be called standard Ethernet Tx Irq Handler |
;------------------------------------------------------ |
|
pop ecx esi ax |
|
;---------------------------------- |
; RX irq |
.not_tx: |
test ax, CSR5_RI |
test eax, CSR5_RI |
jz .not_rx |
push ax esi ecx |
push eax esi ecx |
|
DEBUGF 1,"RX ok!\n" |
|
1118,34 → 1265,30 |
pop ebx |
|
; get current descriptor |
mov edi, [ebx + device.rx_p_des] |
mov eax, [ebx + device.rx_crt_des] |
mov edx, sizeof.DES |
mov eax, [ebx + device.cur_rx] |
mov edx, sizeof.desc |
mul edx |
add edi, eax |
lea edi, [ebx + device.rx_ring + eax] |
|
; now check status |
mov eax, [edi + DES.status] |
mov eax, [edi + desc.status] |
|
test eax, DES0_OWN |
jnz .end_rx ; current desc is busy, nothing to do |
|
test eax, RDES0_FS |
jz .end_rx ; current desc is NOT first packet, ERROR! |
|
test eax, RDES0_LS ; if not last desc of packet, error for now |
jz .end_rx |
|
test eax, RDES0_ES |
jnz .end_rx |
|
mov esi, [edi + DES.virtaddr] |
mov ecx, [edi + DES.status] |
mov esi, [edi + RX_RING_SIZE*sizeof.desc] |
mov ecx, [edi + desc.status] |
shr ecx, RDES0_FL_SH |
and ecx, RDES0_FL_MASK |
sub ecx, 4 ; crc, we dont need it |
|
DEBUGF 1,"Received packet!, size=%u, addr:%x\n", ecx, esi |
DEBUGF 1,"size=%u, addr:0x%x\n", ecx, esi |
|
push esi edi ecx |
invoke KernelAlloc, ecx ; Allocate a buffer to put packet into |
1156,7 → 1299,7 |
push ebx |
push dword .rx_loop |
push ecx eax |
mov edi, eax |
xchg edi, eax |
|
; update statistics |
inc [ebx + device.packets_rx] |
1174,16 → 1317,16 |
.nw: |
rep movsd |
|
mov [edi + DES.status], DES0_OWN ; free descriptor |
mov [eax + desc.status], DES0_OWN ; free descriptor |
|
inc [ebx + device.rx_crt_des] ; next descriptor |
and [ebx + device.rx_crt_des], RX_DES_COUNT-1 |
inc [ebx + device.cur_rx] ; next descriptor |
and [ebx + device.cur_rx], RX_RING_SIZE-1 |
|
jmp [Eth_input] |
|
.end_rx: |
.fail: |
pop ecx esi ax |
pop ecx esi eax |
.not_rx: |
|
pop edi esi ebx |
1194,7 → 1337,7 |
align 4 |
write_mac: ; in: mac pushed onto stack (as 3 words) |
|
DEBUGF 2,"Writing MAC: " |
DEBUGF 1,"Writing MAC\n" |
|
; write data into driver cache |
mov esi, esp |
1203,22 → 1346,13 |
movsw |
add esp, 6 |
|
; send setup packet (only if driver is started) |
call Send_Setup_Packet |
;; send setup packet (only if driver is started) |
;; call Create_Setup_Packet |
|
align 4 |
read_mac: |
|
DEBUGF 1,"Read_mac\n" |
|
ret |
|
|
|
align 4 |
read_mac_eeprom: |
|
DEBUGF 1,"Read_mac_eeprom\n" |
DEBUGF 1,"Reading MAC from eeprom\n" |
|
lea edi, [ebx + device.mac] |
mov esi, 20/2 ; read words, start address is 20 |
1231,22 → 1365,15 |
cmp esi, 26/2 |
jb .loop |
|
DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2 |
DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2 |
|
ret |
|
align 4 |
write_mac_eeprom: |
|
DEBUGF 1,"Write_mac_eeprom\n" |
|
ret |
|
|
align 4 |
SROM_GetWidth: ; should be 6 or 8 according to some manuals (returns in ecx) |
|
DEBUGF 1,"SROM_GetWidth\n" |
; DEBUGF 1,"SROM_GetWidth\n" |
|
call SROM_Idle |
call SROM_EnterAccessMode |
1290,7 → 1417,7 |
jbe .loop2 |
.end_loop2: |
|
DEBUGF 1,"Srom width=%u\n", ecx |
DEBUGF 1,"SROM width=%u\n", ecx |
|
call SROM_Idle |
call SROM_EnterAccessMode |
1316,7 → 1443,7 |
align 4 |
SROM_EnterAccessMode: |
|
DEBUGF 1,"SROM_EnterAccessMode\n" |
; DEBUGF 1,"SROM_EnterAccessMode\n" |
|
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR9 |
1340,7 → 1467,7 |
align 4 |
SROM_Idle: |
|
DEBUGF 1,"SROM_Idle\n" |
; DEBUGF 1,"SROM_Idle\n" |
|
call SROM_EnterAccessMode |
|
1381,7 → 1508,7 |
align 4 |
SROM_Read_Word: |
|
DEBUGF 1,"SROM_Read_word at: %x result: ", esi |
; DEBUGF 1,"SROM_Read_word at: %x\n", esi |
|
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], CSR9 |
1439,20 → 1566,12 |
|
mov eax, esi |
|
DEBUGF 1,"%x\n", ax |
; DEBUGF 1,"%x\n", ax |
|
ret |
|
|
|
|
|
|
|
;<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
|
|
|
;********************************************************************* |
;* Media Descriptor Code * |
;********************************************************************* |
1485,7 → 1604,7 |
align 4 |
mdio_read: ; phy_id:edx, location:esi |
|
DEBUGF 1,"mdio read, phy=%x, location=%x", edx, esi |
DEBUGF 1,"mdio read, phy=%x, location=%x\n", edx, esi |
|
shl edx, 5 |
or esi, edx |
1579,7 → 1698,7 |
shr esi, 1 |
movzx eax, si |
|
DEBUGF 1,", data=%x\n", ax |
DEBUGF 1,"data=%x\n", ax |
|
ret |
|
1677,6 → 1796,10 |
ret |
|
|
|
|
|
|
; End of code |
|
data fixups |
1686,9 → 1809,29 |
|
my_service db 'DEC21X4X',0 ; max 16 chars include zero |
|
chiplist: |
; PCI id's , chip ,IO size, CSR7 , name , flags |
dd 0x00021011, DC21040, 128, 0x0001ebef, sz_040, 0 |
dd 0x00141011, DC21041, 128, 0x0001ebef, sz_041, FLAG_HAS_MEDIA_TABLE |
dd 0x00091011, DC21140, 128, 0x0001ebef, sz_140, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM |
dd 0x00191011, DC21143, 128, 0x0001ebef, sz_143, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_ALWAYS_CHECK_MII or FLAG_HAS_ACPI |
dd 0x000211AD, LC82C168, 256, 0x0801fbff, sz_lite, FLAG_HAS_MII |
dd 0x051210D9, MX98713, 128, 0x0001ebef, sz_m512, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE |
dd 0x053110D9, MX98715, 256, 0x0001ebef, sz_m513, FLAG_HAS_MEDIA_TABLE |
dd 0x1400125B, MX98725, 128, 0x0001fbff, sz_asix, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM |
dd 0 |
|
sz_040 db "Digital DC21040 Tulip", 0 |
sz_041 db "Digital DC21041 Tulip", 0 |
sz_140 db "Digital DS21140 Tulip", 0 |
sz_143 db "Digital DS21143 Tulip", 0 |
sz_lite db "Lite-On 82c168 PNIC", 0 |
sz_m512 db "Macronix 98713 PMAC", 0 |
sz_m513 db "Macronix 987x5 PMAC", 0 |
sz_asix db "ASIX AX88140", 0 |
|
include_debug_strings ; All data wich FDO uses will be included here |
|
align 4 |
devices dd 0 |
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling |
|
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling |