From 34efef1da5b8fc343aaf16354fa8b02c3a714781 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Fri, 11 Jun 2010 16:44:47 +0000 Subject: [PATCH] Updates in RTL8029 and PCNET32 driver. Moved public data structure for network drivers to netdrv.inc git-svn-id: svn://kolibrios.org@1492 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/drivers/3c59x.asm | 36 +- kernel/branches/net/drivers/RTL8029.asm | 467 ++++++--------- kernel/branches/net/drivers/RTL8139.asm | 41 +- kernel/branches/net/drivers/netdrv.inc | 37 +- kernel/branches/net/drivers/pcnet32.asm | 717 ++++++++++-------------- 5 files changed, 538 insertions(+), 760 deletions(-) diff --git a/kernel/branches/net/drivers/3c59x.asm b/kernel/branches/net/drivers/3c59x.asm index 24e55e1048..6c56dcb8b3 100644 --- a/kernel/branches/net/drivers/3c59x.asm +++ b/kernel/branches/net/drivers/3c59x.asm @@ -102,7 +102,7 @@ include 'fdo.inc' include 'netdrv.inc' -OS_BASE equ 0; +OS_BASE equ 0 new_app_base equ 0x60400000 PROC_BASE equ OS_BASE+0x0080000 @@ -111,24 +111,11 @@ public service_proc public version -struc ETH_DEVICE { -; pointers to procedures - .unload dd ? - .reset dd ? - .transmit dd ? - .set_MAC dd ? - .get_MAC dd ? - .set_mode dd ? - .get_mode dd ? -; status & variables - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) - .name dd ? - .mac dp ? -; device specific +virtual at ebx + + device: + + ETH_DEVICE .rx_buffer dd ? .tx_buffer dd ? @@ -152,10 +139,6 @@ struc ETH_DEVICE { .size = $ - device -} - -virtual at ebx - device ETH_DEVICE end virtual @@ -530,17 +513,12 @@ proc service_proc stdcall, ioctl:dword mov [device.pci_dev], cl ; Now, it's time to find the base io addres of the PCI device -; TODO: implement check if bus and dev exist on this machine - find_io [device.pci_bus], [device.pci_dev], [device.io_addr] ; We've found the io address, find IRQ now - movzx ecx, [device.pci_bus] - movzx edx, [device.pci_dev] - stdcall PciRead8, ecx ,edx ,0x3c ; 0x3c is the offset where irq can be found - mov [device.irq_line], al + find_irq [device.pci_bus], [device.pci_dev], [device.irq_line] DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 diff --git a/kernel/branches/net/drivers/RTL8029.asm b/kernel/branches/net/drivers/RTL8029.asm index 08638002de..7471b44f88 100644 --- a/kernel/branches/net/drivers/RTL8029.asm +++ b/kernel/branches/net/drivers/RTL8029.asm @@ -18,7 +18,7 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -$Revision$ +;$Revision$ format MS COFF @@ -31,51 +31,20 @@ __DEBUG_LEVEL__ equ 1 include 'proc32.inc' include 'imports.inc' include 'fdo.inc' +include 'netdrv.inc' -OS_BASE equ 0x80000000 -new_app_base equ 0x0 +OS_BASE equ 0 +new_app_base equ 0x60400000 PROC_BASE equ OS_BASE+0x0080000 -; PCI Bus defines -PCI_HEADER_TYPE equ 0x0e ;8 bit -PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit -PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits -PCI_BASE_ADDRESS_SPACE_IO equ 0x01 -PCI_VENDOR_ID equ 0x00 ;16 bit -PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC -struc IOCTL { - .handle dd ? - .io_code dd ? - .input dd ? - .inp_size dd ? - .output dd ? - .out_size dd ? -} +virtual at ebx -virtual at 0 - IOCTL IOCTL -end virtual + device: -struc ETH_DEVICE { -; pointers to procedures - .unload dd ? - .reset dd ? - .transmit dd ? - .set_MAC dd ? - .get_MAC dd ? - .set_mode dd ? - .get_mode dd ? -; status - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) - .name dd ? - .mac dp ? -; device specific - .io_addr dw ? + ETH_DEVICE + + .io_addr dd ? .irq_line db ? .pci_bus db ? .pci_dev db ? @@ -89,19 +58,17 @@ struc ETH_DEVICE { .bmem dd ? .rmem dd ? .romdata rb 16 - .size: -} + .size = $ - device -virtual at 0 - device ETH_DEVICE end virtual + public START public service_proc public version - MAX_ne2000 equ 16 ; Max number of devices this driver may handle + MAX_DEVICES equ 16 ; Max number of devices this driver may handle P0_PSTART equ 0x01 P0_PSTOP equ 0x02 @@ -190,24 +157,6 @@ public version ISA_MAX_ADDR equ 0x400 -;------------------------------------------------ - - LAST_IO = 0 - -macro set_io addr { - - if addr = 0 - mov dx, [ebp + device.io_addr] - else - add edx, addr - LAST_IO - end if - - LAST_IO = addr - - -} - -;------------------------------------------------- section '.flat' code readable align 16 @@ -218,6 +167,7 @@ section '.flat' code readable align 16 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 4 proc START stdcall, state:dword cmp [state], 1 @@ -239,25 +189,24 @@ endp ;; proc SERVICE_PROC ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -align 4 -proc service_proc ;stdcall, ioctl:dword - push ebp - mov edx, [esp+8];[ioctl] - mov eax, [edx+IOCTL.io_code] +align 4 +proc service_proc stdcall, ioctl:dword + + mov edx, [ioctl] + mov eax, [IOCTL.io_code] ;------------------------------------------------------ ;--------------- cmp eax, 0 ;SRV_GETVERSION jne @F ;--------------- - cmp [edx+IOCTL.out_size], 4 + cmp [IOCTL.out_size], 4 jl .fail - mov eax, [edx+IOCTL.output] + mov eax, [IOCTL.output] mov [eax], dword API_VERSION xor eax, eax - pop ebp ret 4 ;------------------------------------------------------ @@ -267,14 +216,14 @@ proc service_proc ;stdcall, ioctl:dword DEBUGF 2,"Checking if device is already listed..\n" - mov eax, [edx+IOCTL.input] + mov eax, [IOCTL.input] - cmp [edx+IOCTL.inp_size], 3 + cmp [IOCTL.inp_size], 3 jl .fail cmp byte [eax], 1 je .pci - cmp [edx+IOCTL.inp_size], 4 + cmp [IOCTL.inp_size], 4 jl .fail cmp byte [eax], 0 je .isa @@ -283,80 +232,57 @@ proc service_proc ;stdcall, ioctl:dword .pci: - mov esi, ne2000_LIST - mov ecx, [ne2000_DEV] +; check if the device is already listed + + mov esi, DEVICE_LIST + mov ecx, [DEVICES] test ecx, ecx jz .firstdevice_pci - mov bx , [eax+1] + +; mov eax, [IOCTL.input] ; get the pci bus and device numbers + mov ax , [eax+1] ; .nextdevice: - lodsd - cmp bx , word [eax + device.pci_bus] ; compare with pci and device num in ne2000 list - je find_device_num + mov ebx, [esi] + cmp ax , word [device.pci_bus] ; compare with pci and device num in device list (notice the usage of word instead of byte) + je .find_devicenum ; Device is already loaded, let's find it's device number + add esi, 4 loop .nextdevice .firstdevice_pci: call create_new_struct - mov eax, [edx+IOCTL.input] ; save the pci bus and device numbers - mov cx , [eax+1] ; - mov [ebx+device.pci_bus], cl ; - mov [ebx+device.pci_dev], ch ; + mov eax, [IOCTL.input] + mov cl , [eax+1] + mov [device.pci_bus], cl + mov cl , [eax+2] + mov [device.pci_dev], cl - mov edx, PCI_BASE_ADDRESS_0 ; find the base io address - .sb_reg_check: +; Now, it's time to find the base io addres of the PCI device - movzx eax, byte [ebx+device.pci_bus] ; - movzx ecx, byte [ebx+device.pci_dev] ; - ; - push edx ecx - stdcall PciRead16, eax ,ecx ,edx ; - pop ecx edx - ; - mov [ebx+device.io_addr], ax ; - and eax, PCI_BASE_ADDRESS_IO_MASK ; - test eax, eax ; - jz .sb_inc_reg ; - movzx eax, [ebx+device.io_addr] ; - and eax, PCI_BASE_ADDRESS_SPACE_IO ; - test eax, eax ; - jz .sb_inc_reg ; - ; - movzx eax, [ebx+device.io_addr] ; - and eax, PCI_BASE_ADDRESS_IO_MASK ; - mov [ebx+device.io_addr], ax ; - ; - jmp .got_io ; - ; - .sb_inc_reg: ; - add edx, 4 ; - cmp edx, PCI_BASE_ADDRESS_5 ; - jbe .sb_reg_check ; + find_io [device.pci_bus], [device.pci_dev], [device.io_addr] - .got_io: - movzx eax, byte [ebx+device.pci_bus] ; find IRQ line - movzx ecx, byte [ebx+device.pci_dev] ; - push ebx - stdcall PciRead8, eax ,ecx ,0x3c ; 0x3c is the offset where irq can be found - pop ebx - mov byte [ebx+device.irq_line], al ; +; We've found the io address, find IRQ now + + find_irq [device.pci_bus], [device.pci_dev], [device.irq_line] jmp .hook .isa: - mov esi, ne2000_LIST - mov ecx, [ne2000_DEV] + mov esi, DEVICE_LIST + mov ecx, [DEVICES] test ecx, ecx jz .firstdevice_isa - mov bx , [eax+1] - mov dl , [eax+3] + mov al , [eax+3] + movzx edi, word [eax+1] .nextdevice_isa: - lodsd - cmp bx , [eax + device.io_addr] + mov ebx, [esi] + cmp edi, [device.io_addr] jne .maybenext - cmp dl , [eax + device.irq_line] + cmp al , [device.irq_line] je find_device_num .maybenext: + add esi, 4 loop .nextdevice_isa @@ -364,31 +290,44 @@ proc service_proc ;stdcall, ioctl:dword .firstdevice_isa: call create_new_struct - mov eax, [edx+IOCTL.input] - mov cx , [eax+1] - mov [ebx+device.io_addr], cx + mov eax, [IOCTL.input] + movzx ecx , word [eax+1] + mov [device.io_addr], ecx mov cl, [eax+3] - mov [ebx+device.irq_line], cl + mov [device.irq_line], cl .hook: - 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]:4 + DEBUGF 2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ + [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 call probe ; this function will output in eax test eax, eax jnz .err ; If an error occured, exit - mov eax, [ne2000_DEV] - mov [ne2000_LIST+4*eax], ebx - inc [ne2000_DEV] + mov eax, [DEVICES] + mov [DEVICE_LIST+4*eax], ebx + inc [DEVICES] call EthRegDev ; Register the device to kernel (ebx points to device struct) cmp eax, -1 jz .err - pop ebp ret 4 + +; If the device was already loaded, find the device number and return it in eax + + .find_devicenum: + DEBUGF 1,"Trying to find device number of already registered device\n" + mov ebx, eax + call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + ; into a device number in edi + mov eax, edi ; Application wants it in eax instead + DEBUGF 1,"Kernel says: %u\n", eax + ret + .err: + DEBUGF 1,"Failed, removing device structure\n" stdcall KernelFree, ebx jmp .fail @@ -397,7 +336,6 @@ proc service_proc ;stdcall, ioctl:dword @@: .fail: or eax, -1 - pop ebp ret 4 ;------------------------------------------------------ @@ -406,7 +344,7 @@ endp create_new_struct: - cmp [ne2000_DEV], MAX_ne2000 + cmp [DEVICES], MAX_DEVICES jge .fail push edx @@ -416,12 +354,12 @@ create_new_struct: jz .fail mov ebx, eax - mov dword [ebx+device.reset], reset - mov dword [ebx+device.transmit], transmit - mov dword [ebx+device.get_MAC], read_mac - mov dword [ebx+device.set_MAC], write_mac - mov dword [ebx+device.unload], unload - mov dword [ebx+device.name], my_service + mov [device.reset], reset + mov [device.transmit], transmit + mov [device.get_MAC], read_mac + mov [device.set_MAC], write_mac + mov [device.unload], unload + mov [device.name], my_service ret @@ -458,25 +396,21 @@ unload: ; TODO ;; ;; probe: enables the device and clears the rx buffer ;; -;; Destroys: eax, ebx, ecx, edx -;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; probe: - mov ebp, ebx ;--- - - mov [ebp + device.vendor], VENDOR_NONE - mov [ebp + device.bmem], 0 - mov ax, [ebp + device.io_addr] - add ax, NE_ASIC_OFFSET - mov [ebp + device.asic_base], ax + mov [device.vendor], VENDOR_NONE + mov [device.bmem], 0 + mov eax,[device.io_addr] + add eax, NE_ASIC_OFFSET + mov [device.asic_base], ax DEBUGF 2,"Trying 16-bit mode\n" - or [ebp + device.flags], FLAG_16BIT or FLAG_PIO - mov [ebp + device.memsize], MEM_32768 - mov [ebp + device.tx_start], 64 - mov [ebp + device.rx_start], TXBUF_SIZE + 64 + or [device.flags], FLAG_16BIT or FLAG_PIO + mov [device.memsize], MEM_32768 + mov [device.tx_start], 64 + mov [device.rx_start], TXBUF_SIZE + 64 set_io 0 set_io P0_DCR @@ -492,16 +426,16 @@ probe: out dx, al mov esi, test_data - mov bx, 16384 + mov di, 16384 mov cx, 14 call eth_pio_write - mov bx, 16384 + mov si, 16384 mov cx, 14 - lea edi, [ebp + device.romdata] + lea edi, [device.romdata] call eth_pio_read - lea esi, [ebp + device.romdata] + lea esi, [device.romdata] mov edi, test_data mov ecx, 13 @@ -511,12 +445,12 @@ probe: DEBUGF 2,"Trying 8-bit mode\n" - mov [ebp + device.flags], FLAG_PIO - mov [ebp + device.memsize], MEM_16384 - mov [ebp + device.tx_start], 32 - mov [ebp + device.rx_start], TXBUF_SIZE + 32 + mov [device.flags], FLAG_PIO + mov [device.memsize], MEM_16384 + mov [device.tx_start], 32 + mov [device.rx_start], TXBUF_SIZE + 32 - mov dx, [ebp + device.asic_base] + mov dx, [device.asic_base] add dx, NE_RESET in al, dx @@ -545,17 +479,17 @@ probe: out dx, al mov esi, test_data - mov bx, 8192 + mov di, 8192 mov cx, 14 call eth_pio_write - mov bx, 8192 + mov si, 8192 mov cx, 14 - lea edi, [ebp + device.romdata] + lea edi, [device.romdata] call eth_pio_read mov esi, test_data - lea edi, [ebp + device.romdata] + lea edi, [device.romdata] mov ecx, 13 repz cmpsb @@ -568,60 +502,52 @@ probe: ep_set_vendor: - cmp [ebp + device.io_addr], ISA_MAX_ADDR + cmp [device.io_addr], ISA_MAX_ADDR jbe ep_001 DEBUGF 2,"Card is using PCI bus\n" -;;; or [ebp + device.flags], FLAG_16BIT +; or [flags], FLAG_16BIT ep_001: - mov [ebp + device.vendor], VENDOR_NOVELL + mov [device.vendor], VENDOR_NOVELL ep_check_have_vendor: - mov ebx, ebp ;---- - mov al, [ebp + device.vendor] + mov al, [device.vendor] cmp al, VENDOR_NONE - ;;;; je rtl8029_exit +; je rtl8029_exit cmp al, VENDOR_3COM je reset - mov eax, [ebp + device.bmem] - mov [ebp + device.rmem], eax + mov eax, [device.bmem] + mov [device.rmem], eax - ;-- hack (read mac from eeprom ant write it to hardware's register) - mov ebx, ebp call read_mac push .hack sub esp, 6 mov edi, esp - lea esi, [ebp + device.mac] + lea esi, [device.mac] movsd movsw jmp write_mac .hack: - ;--- hack ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; reset: Place the chip into a virgin state ;; -;; Destroys: eax, ebx, ecx, edx -;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; reset: - mov ebp, ebx ;--- - DEBUGF 2,"Resetting device\n" ; attach int handler - movzx eax, [ebp+device.irq_line] + movzx eax, [device.irq_line] DEBUGF 1,"Attaching int handler to irq %x\n",eax:1 stdcall AttachIntHandler, eax, int_handler, dword 0 @@ -632,7 +558,7 @@ reset: out dx, al set_io P0_DCR - test [ebp + device.flags], FLAG_16BIT + test [device.flags], FLAG_16BIT jz nsr_001 mov al, 0x49 @@ -644,7 +570,6 @@ nsr_001: nsr_002: out dx, al - ;clear remote bytes count set_io 0 @@ -671,7 +596,7 @@ nsr_002: ; transmit page stuff set_io P0_TPSR - mov al, [ebp + device.tx_start] + mov al, [device.tx_start] out dx, al ; set receive control register ;;;; @@ -681,17 +606,17 @@ nsr_002: ; pagestart set_io P0_PSTART - mov al, [ebp + device.rx_start] + mov al, [device.rx_start] out dx, al ; pagestop set_io P0_PSTOP - mov al, [ebp + device.memsize] + mov al, [device.memsize] out dx, al ; page boundary set_io P0_BOUND - mov al, [ebp + device.memsize] + mov al, [device.memsize] dec al out dx, al @@ -706,7 +631,7 @@ nsr_002: out dx, al set_io P1_CURR - mov al, [ebp + device.rx_start] + mov al, [device.rx_start] out dx, al set_io 0 @@ -714,7 +639,6 @@ nsr_002: out dx, al ; Read MAC address - mov ebx, ebp ;---- call read_mac ; clear interupt status @@ -739,17 +663,13 @@ nsr_002: out dx, al ; clear packet/byte counters - - lea edi, [ebp+device.bytes_tx] + xor eax, eax + lea edi, [device.bytes_tx] mov ecx, 6 rep stosd - ; Indicate that we have successfully reset the card DEBUGF 2,"Done!\n" - xor eax, eax - - mov ebx, ebp ;------ ret @@ -761,22 +681,23 @@ nsr_002: ; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx ;*************************************************************************** +; TODO: use a RING-buffer + align 4 transmit: - mov ebp, ebx mov esi, [esp + 4] mov ecx, [esp + 8] DEBUGF 2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx DEBUGF 2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2 - cmp dword [esp + 8], ETH_FRAME_LEN - jg .finish ; packet is too long - cmp dword [esp + 8], 60 - jl .finish ; packet is too short + cmp ecx, ETH_FRAME_LEN + jg .err ; packet is too long + cmp ecx, 60 + jl .err ; packet is too short - xor bl, bl - mov bh, [ebp + device.tx_start] + movzx edi, [device.tx_start] + shl edi, 8 push cx call eth_pio_write pop cx @@ -786,7 +707,7 @@ transmit: out dx, al set_io P0_TPSR - mov al, [ebp + device.tx_start] + mov al, [device.tx_start] out dx, al set_io P0_TBCR0 @@ -803,15 +724,18 @@ transmit: DEBUGF 2," - Packet Sent!\n" - inc [ebp+device.packets_tx] ; + inc [device.packets_tx] mov eax, [esp + 8] ; Get packet size in eax - add dword [ebp + device.bytes_tx], eax - adc dword [ebp + device.bytes_tx + 4], 0 -.finish: - mov ebx, ebp - xor eax, eax + add dword [device.bytes_tx], eax + adc dword [device.bytes_tx + 4], 0 +.finish: + xor eax, eax + ret + +.err: + or eax, -1 ret @@ -826,10 +750,10 @@ int_handler: DEBUGF 2,"IRQ %x ",eax:2 ; find pointer of device wich made INT occur - mov esi, ne2000_LIST - mov ecx, [ne2000_DEV] + mov esi, DEVICE_LIST + mov ecx, [DEVICES] .nextdevice: - mov ebp, dword [esi] + mov ebx, [esi] set_io 0 set_io P0_ISR @@ -878,10 +802,10 @@ int_handler: in al, dx inc al - cmp al, [ebp + device.memsize] + cmp al, [device.memsize] jb .nsp_001 - mov al, [ebp + device.rx_start] + mov al, [device.rx_start] .nsp_001: mov ch, al @@ -898,10 +822,10 @@ int_handler: mov al, CMD_PS0 out dx, al - cmp cl, [ebp + device.memsize] + cmp cl, [device.memsize] jb .nsp_002 - mov cl, [ebp + device.rx_start] + mov cl, [device.rx_start] .nsp_002: cmp cl, ch @@ -912,18 +836,18 @@ int_handler: mov [pktoff], ax - mov al, [ebp + device.flags] + mov al, [device.flags] test al, FLAG_PIO jz .nsp_003 - mov bx, word [pktoff] + mov si, word [pktoff] lea edi, [pkthdr] mov cx, 4 call eth_pio_read jmp .nsp_004 .nsp_003: - mov edi, [ebp + device.rmem] + mov edi, [device.rmem] movzx eax, word [pktoff] add edi, eax mov eax, [edi] @@ -938,9 +862,9 @@ int_handler: DEBUGF 2,"Received %u bytes\n",eax - add dword [ebp + device.bytes_rx], eax ; Update stats - adc dword [ebp + device.bytes_rx + 4], 0 - inc dword [ebp + device.packets_rx] ; + add dword [device.bytes_rx], eax ; Update stats + adc dword [device.bytes_rx + 4], 0 + inc dword [device.packets_rx] ; mov [eth_tmp_len], ax mov dword[size], eax @@ -957,25 +881,24 @@ int_handler: ; Right, we can now get the data - xor ebx, ebx - mov bh , [ebp + device.memsize] - sub bx , [pktoff] + movzx esi, [device.memsize] + sub si , [pktoff] - cmp [eth_tmp_len], bx + cmp [eth_tmp_len], si jbe .nsp_005 DEBUGF 2,"WRAP!\n" - mov al , [ebp + device.flags] + mov al , [device.flags] test al , FLAG_PIO jz .nsp_006 - push ebx - mov cx , bx - mov bx , [pktoff+4] + push esi + mov cx , si + mov si , [pktoff+4] mov edi, [eth_rx_data_ptr+4] call eth_pio_read - pop ebx + pop esi jmp .nsp_007 .nsp_006: @@ -984,20 +907,18 @@ int_handler: .nsp_007: xor al, al - mov ah, [ebp + device.rx_start] + mov ah, [device.rx_start] mov [pktoff], ax - add [eth_rx_data_ptr], ebx - sub [eth_tmp_len], bx + add [eth_rx_data_ptr], esi + sub [eth_tmp_len], si .nsp_005: - test [ebp + device.flags], FLAG_PIO + test [device.flags], FLAG_PIO jz .nsp_008 - xor ebx, ebx - mov bx, [pktoff] - xor ecx, ecx - mov cx, [eth_tmp_len] + movzx esi, word [pktoff] + movzx ecx, word [eth_tmp_len] mov edi, [eth_rx_data_ptr] call eth_pio_read jmp .nsp_009 @@ -1008,10 +929,10 @@ int_handler: .nsp_009: mov al, [pkthdr+1] - cmp al, [ebp + device.rx_start] + cmp al, [device.rx_start] jne .nsp_010 - mov al, [ebp + device.memsize] + mov al, [device.memsize] .nsp_010: set_io 0 @@ -1019,10 +940,7 @@ int_handler: dec al out dx, al - mov ebx, ebp add esp, 14 - - mov ebx, ebp jmp EthReceiver ; send it to the kernel .fail: @@ -1044,8 +962,6 @@ ret align 4 write_mac: ; in: mac on stack (6 bytes) - mov ebp, ebx ;--- - DEBUGF 1,"Writing MAC: " set_io 0 @@ -1063,8 +979,6 @@ write_mac: ; in: mac on stack (6 bytes) add esp, 6 - mov ebx, ebp ;--- - ; Notice this procedure does not ret, but continues to read_mac instead. ;;;;;;;;;;;;;;;;;;;;;; @@ -1075,8 +989,6 @@ write_mac: ; in: mac on stack (6 bytes) read_mac: - mov ebp, ebx ;----- - DEBUGF 1,"Reading MAC: " ; set_io 0 @@ -1084,7 +996,7 @@ read_mac: ; out dx, al ; ; set_io P1_PAR0 -; lea edi, [ebp + device.mac] +; lea edi, [mac] ; ; mov cx, 6 ; .loop: @@ -1097,19 +1009,18 @@ read_mac: ; mov al, CMD_PS0; + CMD_RD2 + CMD_STA ; set page back to 0 ; out dx, al - - mov bx, 0 + mov si, 0 mov cx, 16 - lea edi, [ebp + device.romdata] + lea edi, [device.romdata] call eth_pio_read - lea esi, [ebp + device.romdata] - lea edi, [ebp + device.mac] + lea esi, [device.romdata] + lea edi, [device.mac] mov ecx, 6 .loop: movsb - test [ebp + device.flags], FLAG_16BIT + test [device.flags], FLAG_16BIT jz .8bit inc esi .8bit: @@ -1117,8 +1028,6 @@ read_mac: 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 - mov ebx, ebp ;--- - ret @@ -1128,13 +1037,13 @@ read_mac: ; ; Description ; Read a frame from the ethernet card via Programmed I/O -; src in bx +; src in si ; cnt in cx ; dst in edi ;*************************************************************************** eth_pio_read: - DEBUGF 1,"Eth PIO Read from %x to %x, %u bytes ",bx,edi,cx + DEBUGF 1,"Eth PIO Read from %x to %x, %u bytes ",si,edi,cx set_io 0 mov al, CMD_RD2 + CMD_STA @@ -1148,11 +1057,10 @@ eth_pio_read: set_io P0_RBCR1 out dx, al - mov al, bl + mov ax, si set_io P0_RSAR0 out dx, al - - mov al, bh + shr ax, 8 set_io P0_RSAR1 out dx, al @@ -1160,9 +1068,9 @@ eth_pio_read: set_io 0 out dx, al - mov dx, [ebp + device.asic_base] + mov dx, [device.asic_base] - test [ebp+device.flags], FLAG_16BIT + test [device.flags], FLAG_16BIT jz epr_003 DEBUGF 1,"in 16-bits mode" @@ -1209,13 +1117,13 @@ epr_005: ; Wait for Remote DMA Complete ; ; Description ; writes a frame to the ethernet card via Programmed I/O -; dst in bx +; dst in di ; cnt in cx ; src in esi ;*************************************************************************** eth_pio_write: - DEBUGF 1,"Eth PIO Write from %x to %x, %u bytes ",esi,bx,cx + DEBUGF 1,"Eth PIO Write from %x to %x, %u bytes ",esi,di,cx set_io 0 mov al, CMD_RD2 + CMD_STA @@ -1233,20 +1141,19 @@ eth_pio_write: mov al, ch out dx, al + mov ax, di set_io P0_RSAR0 - mov al, bl out dx, al - + shr ax, 8 set_io P0_RSAR1 - mov al, bh out dx, al set_io 0 mov al, CMD_RD1 + CMD_STA out dx, al - mov dx, [ebp + device.asic_base] - test [ebp + device.flags], FLAG_16BIT + mov dx, [device.asic_base] + test [device.flags], FLAG_16BIT jz epw_003 DEBUGF 1,"in 16-bits mode" @@ -1288,7 +1195,7 @@ epw_005: ; Wait for Remote DMA Complete ;all initialized data place here align 4 -ne2000_DEV dd 0 +DEVICES dd 0 version dd (5 shl 16) or (API_VERSION and 0xFFFF) my_service db 'RTL8029/ne2000',0 ;max 16 chars include zero @@ -1304,7 +1211,7 @@ include_debug_strings section '.data' data readable writable align 16 ;place all uninitialized data place here -ne2000_LIST rd MAX_ne2000 +DEVICE_LIST rd MAX_DEVICES diff --git a/kernel/branches/net/drivers/RTL8139.asm b/kernel/branches/net/drivers/RTL8139.asm index f438c3a70e..c08edf1b3f 100644 --- a/kernel/branches/net/drivers/RTL8139.asm +++ b/kernel/branches/net/drivers/RTL8139.asm @@ -29,7 +29,7 @@ include 'imports.inc' include 'fdo.inc' include 'netdrv.inc' -OS_BASE equ 0; +OS_BASE equ 0 new_app_base equ 0x60400000 PROC_BASE equ OS_BASE+0x0080000 @@ -38,24 +38,12 @@ public service_proc public version -struc ETH_DEVICE { -; pointers to procedures - .unload dd ? - .reset dd ? - .transmit dd ? - .set_MAC dd ? - .get_MAC dd ? - .set_mode dd ? - .get_mode dd ? -; status & variables - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) - .name dd ? - .mac dp ? -; device specific +virtual at ebx + + device: + + ETH_DEVICE + .rx_buffer dd ? .tx_buffer dd ? .rx_data_offset dd ? @@ -68,12 +56,9 @@ struc ETH_DEVICE { .size = $ - device -} - -virtual at ebx - device ETH_DEVICE end virtual + ; RTL8139 specific defines MAX_RTL8139 equ 16 ; Max number of devices this driver may handle @@ -334,7 +319,7 @@ proc service_proc stdcall, ioctl:dword jge .fail push edx - stdcall KernelAlloc, dword device.size ; Allocate the buffer for eth_device structure + stdcall KernelAlloc, device.size ; Allocate the buffer for eth_device structure pop edx test eax, eax jz .fail @@ -358,18 +343,12 @@ proc service_proc stdcall, ioctl:dword mov [device.pci_dev], cl ; Now, it's time to find the base io addres of the PCI device -; TODO: implement check if bus and dev exist on this machine find_io [device.pci_bus], [device.pci_dev], [device.io_addr] ; We've found the io address, find IRQ now - movzx eax, byte [device.pci_bus] - movzx ecx, byte [device.pci_dev] - push ebx - stdcall PciRead8, eax ,ecx ,0x3c ; 0x3c is the offset where irq can be found - pop ebx - mov byte [device.irq_line], al + find_irq [device.pci_bus], [device.pci_dev], [device.irq_line] DEBUGF 2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 diff --git a/kernel/branches/net/drivers/netdrv.inc b/kernel/branches/net/drivers/netdrv.inc index defb6ffb90..3e0980ae99 100644 --- a/kernel/branches/net/drivers/netdrv.inc +++ b/kernel/branches/net/drivers/netdrv.inc @@ -112,13 +112,24 @@ macro find_io bus, dev, io { } +macro find_irq bus, dev, irq { + + push eax edx ecx + movzx ecx, bus + movzx edx, dev + stdcall PciRead8, ecx ,edx ,0x3c ; 0x3c is the offset where irq can be found + mov irq, al + pop ecx edx eax + +} + macro make_bus_master bus, dev { movzx ecx, bus movzx edx, dev - stdcall PciRead32, ecx ,edx ,PCI_REG_COMMAND + stdcall PciRead32, ecx ,edx, PCI_REG_COMMAND or al, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) and al, not (1 shl PCI_BIT_MMIO) @@ -163,4 +174,26 @@ macro virt_to_dma { ; input is eax inc esp inc esp -} \ No newline at end of file +} + + +;struc ETH_DEVICE { +macro ETH_DEVICE { +; pointers to procedures + .unload dd ? + .reset dd ? + .transmit dd ? + .set_MAC dd ? + .get_MAC dd ? + .set_mode dd ? + .get_mode dd ? +; status + .bytes_tx dq ? + .bytes_rx dq ? + .packets_tx dd ? + .packets_rx dd ? + .mode dd ? + .name dd ? + .mac dp ? +} + diff --git a/kernel/branches/net/drivers/pcnet32.asm b/kernel/branches/net/drivers/pcnet32.asm index 840a568e10..75d5d9b9f3 100644 --- a/kernel/branches/net/drivers/pcnet32.asm +++ b/kernel/branches/net/drivers/pcnet32.asm @@ -26,8 +26,10 @@ MAX_ETH_FRAME_SIZE equ 1514 include 'proc32.inc' include 'imports.inc' include 'fdo.inc' +include 'netdrv.inc' -OS_BASE equ 0; + +OS_BASE equ 0 new_app_base equ 0x60400000 PROC_BASE equ OS_BASE+0x0080000 @@ -35,37 +37,12 @@ public START public service_proc public version -struc IOCTL { - .handle dd ? - .io_code dd ? - .input dd ? - .inp_size dd ? - .output dd ? - .out_size dd ? -} -virtual at 0 - IOCTL IOCTL -end virtual +virtual at ebx -struc ETH_DEVICE { -; pointers to procedures - .unload dd ? - .reset dd ? - .transmit dd ? - .set_MAC dd ? - .get_MAC dd ? - .set_mode dd ? - .get_mode dd ? -; status - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) - .name dd ? - .mac dp ? -; device specific + device: + + ETH_DEVICE .rx_buffer dd ? .tx_buffer dd ? @@ -74,10 +51,19 @@ struc ETH_DEVICE { .irq_line db ? .pci_bus db ? .pci_dev db ? + db ? ; align 4 + + .access_read_csr dd ? + .access_write_csr dd ? + .access_read_bcr dd ? + .access_write_bcr dd ? + .access_read_rap dd ? + .access_write_rap dd ? + .access_reset dd ? ; The following fields up to .tx_ring_phys inclusive form - ; initialization block for hardware; do not modify - align 4 ; initialization block must be dword-aligned + ; initialization block for hardware; do not modify (must be 4-aligned) + .private: .mode_ dw ? .tlen_rlen dw ? @@ -102,20 +88,8 @@ struc ETH_DEVICE { .fset db ? .fdx db ? - .access_read_csr dd ? - .access_write_csr dd ? - .access_read_bcr dd ? - .access_write_bcr dd ? - .access_read_rap dd ? - .access_write_rap dd ? - .access_reset dd ? + .size = $ - device - .size: - -} - -virtual at 0 - device ETH_DEVICE end virtual struc buf_head { @@ -440,6 +414,7 @@ section '.flat' code readable align 16 ;; (standard driver proc) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 4 proc START stdcall, state:dword cmp [state], 1 @@ -447,7 +422,7 @@ proc START stdcall, state:dword .entry: - DEBUGF 1,"Loading PCnet driver\n" + DEBUGF 1,"Loading PCnet driver\n" stdcall RegService, my_service, service_proc ret @@ -470,16 +445,16 @@ align 4 proc service_proc stdcall, ioctl:dword mov edx, [ioctl] - mov eax, [edx+IOCTL.io_code] + mov eax, [IOCTL.io_code] ;------------------------------------------------------ cmp eax, 0 ;SRV_GETVERSION jne @F - cmp [edx+IOCTL.out_size], 4 + cmp [IOCTL.out_size], 4 jl .fail - mov eax, [edx+IOCTL.output] + mov eax, [IOCTL.output] mov [eax], dword API_VERSION xor eax, eax @@ -490,28 +465,27 @@ proc service_proc stdcall, ioctl:dword cmp eax, 1 ;SRV_HOOK jne .fail - mov eax, [esp] - - cmp [edx + IOCTL.inp_size], 3 ; Data input must be at least 3 bytes + cmp [IOCTL.inp_size], 3 ; Data input must be at least 3 bytes jl .fail - mov eax, [edx + IOCTL.input] + mov eax, [IOCTL.input] cmp byte [eax], 1 ; 1 means device number and bus number (pci) are given jne .fail ; other types arent supported for this card yet ; check if the device is already listed - mov esi, PCNET_LIST mov ecx, [PCNET_DEV] test ecx, ecx jz .firstdevice - mov eax, [edx+IOCTL.input] ; get the pci bus and device numbers - mov bx , [eax+1] ; - .nextdevice: - lodsd - cmp bx , word [eax + device.pci_bus] ; compare with pci and device num in RTL8139 list (notice the usage of word instead of byte) - je .find_devicenum ; Device is already loaded, let's find it's device number + mov esi, PCNET_LIST +; mov eax, [IOCTL.input] ; get the pci bus and device numbers + mov ax , [eax+1] ; + .nextdevice: + mov ebx, [esi] + cmp ax , word [device.pci_bus] ; compare with pci and device num in device list (notice the usage of word instead of byte) + je .find_devicenum ; Device is already loaded, let's find it's device number + add esi, 4 loop .nextdevice ; This device doesnt have its own eth_device structure yet, lets create one @@ -529,132 +503,45 @@ proc service_proc stdcall, ioctl:dword ; Fill in the direct call addresses into the struct - mov dword [ebx+device.reset], reset - mov dword [ebx+device.transmit], transmit - mov dword [ebx+device.get_MAC], read_mac - mov dword [ebx+device.set_MAC], write_mac - mov dword [ebx+device.unload], unload - mov dword [ebx+device.name], my_service + mov [device.reset], reset + mov [device.transmit], transmit + mov [device.get_MAC], read_mac + mov [device.set_MAC], write_mac + mov [device.unload], unload + mov [device.name], my_service ; save the pci bus and device numbers - mov eax, [edx+IOCTL.input] + mov eax, [IOCTL.input] mov cl , [eax+1] - mov [ebx+device.pci_bus], cl + mov [device.pci_bus], cl mov cl , [eax+2] - mov [ebx+device.pci_dev], cl + mov [device.pci_dev], cl ; Now, it's time to find the base io addres of the PCI device -; TODO: implement check if bus and dev exist on this machine - mov edx, PCI_BASE_ADDRESS_0 - .reg_check: - movzx eax, byte [ebx+device.pci_bus] - movzx ecx, byte [ebx+device.pci_dev] - - push edx ecx - stdcall PciRead16, eax ,ecx ,edx - pop ecx edx - - mov [ebx+device.io_addr], eax - and eax, PCI_BASE_ADDRESS_IO_MASK - test eax, eax - jz .inc_reg - mov eax, [ebx+device.io_addr] - and eax, PCI_BASE_ADDRESS_SPACE_IO - test eax, eax - jz .inc_reg - - mov eax, [ebx+device.io_addr] - and eax, PCI_BASE_ADDRESS_IO_MASK - mov [ebx+device.io_addr], eax - jmp .got_io - - .inc_reg: - add edx, 4 - cmp edx, PCI_BASE_ADDRESS_5 - jbe .reg_check - - .got_io: + find_io [device.pci_bus], [device.pci_dev], [device.io_addr] ; We've found the io address, find IRQ now - movzx eax, byte [ebx+device.pci_bus] - movzx ecx, byte [ebx+device.pci_dev] - push ebx - stdcall PciRead8, eax ,ecx ,0x3c ; 0x3c is the offset where irq can be found - pop ebx - mov byte [ebx+device.irq_line], al + find_irq [device.pci_bus], [device.pci_dev], [device.irq_line] DEBUGF 1,"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]:4 + [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 + allocate_and_clear [device.tx_buffer], (PCNET_RX_RING_SIZE * PCNET_PKT_BUF_SZ), .err + allocate_and_clear [device.rx_buffer], (PCNET_TX_RING_SIZE * PCNET_PKT_BUF_SZ), .err + allocate_and_clear [device.rx_ring], (PCNET_RX_RING_SIZE * buf_head.size), .err -; Allocate the Receive buffer - - stdcall KernelAlloc, PCNET_RX_RING_SIZE * PCNET_PKT_BUF_SZ - test eax, eax - jz .err - mov [ebx+device.rx_buffer], eax ; Save the address to it into the device struct - -; Allocate the Transmit Buffer - - stdcall KernelAlloc, PCNET_TX_RING_SIZE * PCNET_PKT_BUF_SZ - test eax, eax - jz .err - mov [ebx+device.tx_buffer], eax - -; Allocate the RX Ring - - stdcall KernelAlloc, PCNET_RX_RING_SIZE * buf_head.size - test eax, eax - jz .err - mov dword [ebx + device.rx_ring], eax + mov eax, [device.rx_ring] call GetPgAddr - mov dword [ebx + device.rx_ring_phys], eax + mov [device.rx_ring_phys], eax -; Allocate the TX ring + allocate_and_clear [device.tx_ring], (PCNET_TX_RING_SIZE * buf_head.size), .err - stdcall KernelAlloc, PCNET_TX_RING_SIZE * buf_head.size - test eax, eax - jz .err - mov dword [ebx + device.tx_ring], eax + mov eax, [device.tx_ring] call GetPgAddr - mov dword [ebx + device.tx_ring_phys], eax - -; fill in some of the structure variables - - call switch_to_wio - - mov edi, [ebx + device.rx_ring] - mov ecx, PCNET_RX_RING_SIZE - mov eax, [ebx + device.rx_buffer] - call GetPgAddr - .rx_init: - mov [edi + buf_head.base], eax - mov [edi + buf_head.length], PCNET_PKT_BUF_SZ_NEG - mov [edi + buf_head.status], 0x8000 - and dword [edi + buf_head.msg_length], 0 - and dword [edi + buf_head.reserved], 0 - add eax, PCNET_PKT_BUF_SZ -; inc eax - add edi, buf_head.size - loop .rx_init - - mov edi, [ebx + device.tx_ring] - mov ecx, PCNET_TX_RING_SIZE - mov eax, [ebx + device.tx_buffer] - call GetPgAddr - .tx_init: - mov [edi + buf_head.base], eax - and dword [edi + buf_head.length], 0 - and dword [edi + buf_head.msg_length], 0 - and dword [edi + buf_head.reserved], 0 - add eax, PCNET_PKT_BUF_SZ - add edi, buf_head.size - loop .tx_init - - mov [ebx + device.tlen_rlen],(PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS) + mov [device.tx_ring_phys], eax ; Ok, the eth_device structure is ready, let's probe the device ; Because initialization fires IRQ, IRQ handler must be aware of this device @@ -664,7 +551,7 @@ proc service_proc stdcall, ioctl:dword call probe ; this function will output in eax test eax, eax - jnz .destroy ; If an error occured, exit + jnz .destroy ; If an error occured, exit call EthRegDev cmp eax, -1 @@ -687,12 +574,11 @@ proc service_proc stdcall, ioctl:dword .destroy: ; todo: reset device into virgin state - dec [PCNET_DEV] .err: DEBUGF 1,"Error, removing all data !\n" - stdcall KernelFree, dword [ebx+device.rx_buffer] - stdcall KernelFree, dword [ebx+device.tx_buffer] + stdcall KernelFree, [device.rx_buffer] + stdcall KernelFree, [device.tx_buffer] stdcall KernelFree, ebx .fail: @@ -732,8 +618,44 @@ ret align 4 probe: - mov edx, [ebx + device.io_addr] + make_bus_master [device.pci_bus], [device.pci_dev] + +; first, fill in some of the structure variables + + mov edi, [device.rx_ring] + mov ecx, PCNET_RX_RING_SIZE + mov eax, [device.rx_buffer] + call GetPgAddr + .rx_init: + mov [edi + buf_head.base], eax + mov [edi + buf_head.length], PCNET_PKT_BUF_SZ_NEG + mov [edi + buf_head.status], 0x8000 + and dword [edi + buf_head.msg_length], 0 + and dword [edi + buf_head.reserved], 0 + add eax, PCNET_PKT_BUF_SZ +; inc eax + add edi, buf_head.size + loop .rx_init + + mov edi, [device.tx_ring] + mov ecx, PCNET_TX_RING_SIZE + mov eax, [device.tx_buffer] + call GetPgAddr + .tx_init: + mov [edi + buf_head.base], eax + and dword [edi + buf_head.length], 0 + and dword [edi + buf_head.msg_length], 0 + and dword [edi + buf_head.reserved], 0 + add eax, PCNET_PKT_BUF_SZ + add edi, buf_head.size + loop .tx_init + + mov [device.tlen_rlen], (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS) + + ; First, we must try to use Word operations + call switch_to_wio + set_io 0 call wio_reset xor ecx, ecx @@ -761,19 +683,20 @@ probe: .try_dwio: call dwio_reset + set_io 0 xor ecx, ecx call dwio_read_csr cmp eax, 4 jne .no_dev ; Try Dword I/O - add edx, PCNET_DWIO_RAP + set_io PCNET_DWIO_RAP mov eax, 88 out dx , eax nop nop in eax, dx - sub edx, PCNET_DWIO_RAP + set_io 0 and eax, 0xffff cmp eax, 88 jne .no_dev @@ -789,27 +712,13 @@ probe: mov eax, 1 ret .L1: - ; TODO: remember to use WORD or DWORD operations - -;;; stdcall Sleep, 10 - -;--------------------------------------------- -; Switch to dword operations - - ; DEBUGF 1,"Switching to 32\n" - ; - ; mov ecx, PCNET_DWIO_RDP - ; mov eax, 0 - ; call wio_write_csr - -;--------------------------------------------- mov ecx, PCNET_CSR_CHIPID0 - call [ebx + device.access_read_csr] + call [device.access_read_csr] mov esi, eax mov ecx, PCNET_CSR_CHIPID1 - call [ebx + device.access_read_csr] + call [device.access_read_csr] shl eax, 16 or eax, esi @@ -820,21 +729,21 @@ probe: shr eax, 12 and eax, 0xffff - mov [ebx + device.chip_version], eax + mov [device.chip_version], eax DEBUGF 1,"chip version ok\n" - mov [ebx + device.fdx], 0 - mov [ebx + device.mii], 0 - mov [ebx + device.fset], 0 - mov [ebx + device.dxsuflo], 0 - mov [ebx + device.ltint], 0 + mov [device.fdx], 0 + mov [device.mii], 0 + mov [device.fset], 0 + mov [device.dxsuflo], 0 + mov [device.ltint], 0 cmp eax, 0x2420 je .L2 cmp eax, 0x2430 je .L2 - mov [ebx + device.fdx], 1 + mov [device.fdx], 1 cmp eax, 0x2621 je .L4 @@ -852,123 +761,85 @@ probe: DEBUGF 1,"Invalid chip rev\n" jmp .no_dev .L2: - mov [ebx + device.name], device_l2 + mov [device.name], device_l2 jmp .L10 .L4: - mov [ebx + device.name], device_l4 -; mov [ebx + device.fdx], 1 + mov [device.name], device_l4 +; mov [device.fdx], 1 jmp .L10 .L5: - mov [ebx + device.name], device_l5 -; mov [ebx + device.fdx], 1 - mov [ebx + device.mii], 1 - mov [ebx + device.fset], 1 - mov [ebx + device.ltint], 1 + mov [device.name], device_l5 +; mov [device.fdx], 1 + mov [device.mii], 1 + mov [device.fset], 1 + mov [device.ltint], 1 jmp .L10 .L6: - mov [ebx + device.name], device_l6 -; mov [ebx + device.fdx], 1 - mov [ebx + device.mii], 1 - mov [ebx + device.fset], 1 + mov [device.name], device_l6 +; mov [device.fdx], 1 + mov [device.mii], 1 + mov [device.fset], 1 jmp .L10 .L7: - mov [ebx + device.name], device_l7 -; mov [ebx + device.fdx], 1 - mov [ebx + device.mii], 1 + mov [device.name], device_l7 +; mov [device.fdx], 1 + mov [device.mii], 1 jmp .L10 .L8: - mov [ebx + device.name], device_l8 -; mov [ebx + device.fdx], 1 + mov [device.name], device_l8 +; mov [device.fdx], 1 mov ecx, PCNET_CSR_RXPOLL - call dword [ebx + device.access_read_bcr] - call dword [ebx + device.access_write_bcr] + call [device.access_read_bcr] + call [device.access_write_bcr] jmp .L10 .L9: - mov [ebx + device.name], device_l9 -; mov [ebx + device.fdx], 1 - mov [ebx + device.mii], 1 + mov [device.name], device_l9 +; mov [device.fdx], 1 + mov [device.mii], 1 .L10: - DEBUGF 1,"device name: %s\n",[ebx + device.name] + DEBUGF 1,"device name: %s\n",[device.name] - cmp [ebx + device.fset], 1 + cmp [device.fset], 1 jne .L11 mov ecx, PCNET_BCR_BUSCTL - call [ebx + device.access_read_bcr] + call [device.access_read_bcr] or eax, 0x800 - call [ebx + device.access_write_bcr] + call [device.access_write_bcr] mov ecx, PCNET_CSR_DMACTL - call [ebx + device.access_read_csr] + call [device.access_read_csr] ; and eax, 0xc00 ; or eax, 0xc00 mov eax, 0xc00 - call [ebx + device.access_write_csr] + call [device.access_write_csr] - mov [ebx + device.dxsuflo],1 - mov [ebx + device.ltint],1 + mov [device.dxsuflo],1 + mov [device.ltint],1 .L11: - push ebx - call adjust_pci_device - pop ebx - DEBUGF 1,"PCI done\n" mov eax, PCNET_PORT_ASEL - mov [ebx + device.options], eax - mov [ebx + device.mode_], word 0x0003 - mov [ebx + device.tlen_rlen], word (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS) + mov [device.options], eax + mov [device.mode_], word 0x0003 + mov [device.tlen_rlen], word (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS) - mov dword [ebx + device.filter], 0 - mov dword [ebx + device.filter+4], 0 + mov dword [device.filter], 0 + mov dword [device.filter+4], 0 mov eax, PCNET_IMR mov ecx, PCNET_CSR_IMR ; Write interrupt mask - call [ebx + device.access_write_csr] - -if 0 - - mov ecx, PCNET_BCR_SSTYLE ; Select Software style 2 TODO: freebsd driver uses style 3, why? - mov eax, 2 - call [ebx + device.access_write_bcr] + call [device.access_write_csr] -; ------------ really nescessary??? ---------------- - lea eax, [ebx + device.private] - mov ecx, eax - and ecx, 0xFFF ; KolibriOS PAGE SIZE - call GetPgAddr - add eax, ecx - - and eax, 0xffff - mov ecx, PCNET_CSR_IAB0 - call [ebx + device.access_write_csr] - lea eax, [ebx + device.private] - mov ecx, eax - and ecx, 0xFFF ; KolibriOS PAGE SIZE - call GetPgAddr - add eax, ecx - - shr eax,16 - mov ecx, PCNET_CSR_IAB1 - call [ebx + device.access_write_csr] - - mov ecx, PCNET_CSR_CSR - mov eax, 1 - call [ebx + device.access_write_csr] -; ------------------------------------------------ -end if - -; mov esi, 1 -; call Sleep - +align 4 reset: ; attach int handler - movzx eax, [ebx+device.irq_line] + movzx eax, [device.irq_line] DEBUGF 1,"Attaching int handler to irq %x\n",eax:1 stdcall AttachIntHandler, eax, int_handler, dword 0 test eax, eax @@ -978,109 +849,134 @@ reset: ; ret @@: - mov edx, [ebx + device.io_addr] - call [ebx + device.access_reset] + set_io 0 + call [device.access_reset] ; after a reset, device will be in WIO mode! - ; Switch pcnet32 to 32bit mode - mov ecx, PCNET_BCR_SSTYLE - mov eax, 2 - call [ebx + device.access_write_bcr] +; Switch to dword operations + + DEBUGF 1,"Switching to 32-bit mode\n" + + mov ecx, PCNET_DWIO_RDP + mov eax, 0 + call wio_write_csr + + call switch_to_dwio + +; Lets find out if we are really in 32-bit mode now.. + + set_io 0 + set_io PCNET_DWIO_RAP + mov eax, 88 + out dx , eax + nop + nop + in eax, dx + set_io 0 + and eax, 0xffff + cmp eax, 88 + je .yes_dwio + + call switch_to_wio ; it seem to have failed, reset device again and use wio + set_io 0 + call [device.access_reset] + + .yes_dwio: ; set/reset autoselect bit mov ecx, PCNET_BCR_MISCCFG - call [ebx + device.access_read_bcr] + call [device.access_read_bcr] and eax,not 2 - test [ebx + device.options], PCNET_PORT_ASEL + test [device.options], PCNET_PORT_ASEL jz .L1 or eax, 2 .L1: - call [ebx + device.access_write_bcr] + call [device.access_write_bcr] ; Handle full duplex setting - cmp byte [ebx + device.full_duplex], 0 + cmp byte [device.full_duplex], 0 je .L2 mov ecx, PCNET_BCR_DUPLEX - call [ebx + device.access_read_bcr] + call [device.access_read_bcr] and eax, not 3 - test [ebx + device.options], PCNET_PORT_FD + test [device.options], PCNET_PORT_FD jz .L3 or eax, 1 - cmp [ebx + device.options], PCNET_PORT_FD or PCNET_PORT_AUI + cmp [device.options], PCNET_PORT_FD or PCNET_PORT_AUI jne .L4 or eax, 2 jmp .L4 .L3: - test [ebx + device.options], PCNET_PORT_ASEL + test [device.options], PCNET_PORT_ASEL jz .L4 - cmp [ebx + device.chip_version], 0x2627 + cmp [device.chip_version], 0x2627 jne .L4 or eax, 3 .L4: mov ecx, PCNET_BCR_DUPLEX - call [ebx + device.access_write_bcr] + call [device.access_write_bcr] .L2: ; set/reset GPSI bit in test register mov ecx, 124 - call [ebx + device.access_read_csr] - mov ecx, [ebx + device.options] + call [device.access_read_csr] + mov ecx, [device.options] and ecx, PCNET_PORT_PORTSEL cmp ecx, PCNET_PORT_GPSI jne .L5 or eax, 0x10 .L5: - call [ebx + device.access_write_csr] - cmp [ebx + device.mii], 0 + call [device.access_write_csr] + cmp [device.mii], 0 je .L6 - test [ebx + device.options], PCNET_PORT_ASEL + test [device.options], PCNET_PORT_ASEL jnz .L6 mov ecx, PCNET_BCR_MIICTL - call [ebx + device.access_read_bcr] + call [device.access_read_bcr] and eax,not 0x38 - test [ebx + device.options], PCNET_PORT_FD + test [device.options], PCNET_PORT_FD jz .L7 or eax, 0x10 .L7: - test [ebx + device.options], PCNET_PORT_100 + test [device.options], PCNET_PORT_100 jz .L8 or eax, 0x08 .L8: - call [ebx + device.access_write_bcr] + call [device.access_write_bcr] jmp .L9 .L6: - test [ebx + device.options], PCNET_PORT_ASEL + test [device.options], PCNET_PORT_ASEL jz .L9 mov ecx, PCNET_BCR_MIICTL DEBUGF 1,"ASEL, enable auto-negotiation\n" - call [ebx + device.access_read_bcr] + call [device.access_read_bcr] and eax, not 0x98 or eax, 0x20 - call [ebx + device.access_write_bcr] + call [device.access_write_bcr] .L9: - cmp [ebx + device.ltint],0 + cmp [device.ltint],0 je .L10 mov ecx,5 - call [ebx + device.access_read_csr] + call [device.access_read_csr] or eax,(1 shl 14) - call [ebx + device.access_write_csr] + call [device.access_write_csr] .L10: - mov eax,[ebx + device.options] - and eax,PCNET_PORT_PORTSEL - shl eax,7 - mov [ebx + device.mode_],ax - mov dword [ebx + device.filter], -1 - mov dword [ebx + device.filter+4], -1 + mov eax, [device.options] + and eax, PCNET_PORT_PORTSEL + shl eax, 7 + mov [device.mode_], ax + mov dword [device.filter], -1 + mov dword [device.filter+4], -1 call read_mac - lea esi, [ebx + device.mac] - lea edi, [ebx + device.phys_addr] + lea esi, [device.mac] + lea edi, [device.phys_addr] movsd movsw - lea eax, [ebx + device.private] + lea eax, [device.private] mov ecx, eax and ecx, 0xFFF ; KolibriOS PAGE SIZE call GetPgAddr @@ -1089,51 +985,56 @@ reset: push eax and eax, 0xffff mov ecx, 1 - call [ebx + device.access_write_csr] + call [device.access_write_csr] pop eax shr eax,16 mov ecx,2 - call [ebx + device.access_write_csr] + call [device.access_write_csr] mov ecx,4 mov eax,0x0915 - call [ebx + device.access_write_csr] + call [device.access_write_csr] mov ecx,0 mov eax,1 - call [ebx + device.access_write_csr] + call [device.access_write_csr] - mov [ebx + device.tx_full],0 - mov [ebx + device.cur_rx],0 - mov [ebx + device.cur_tx],0 - mov [ebx + device.dirty_rx],0 - mov [ebx + device.dirty_tx],0 + mov [device.tx_full],0 + mov [device.cur_rx],0 + mov [device.cur_tx],0 + mov [device.dirty_rx],0 + mov [device.dirty_tx],0 mov ecx,100 .L11: push ecx - xor ecx,ecx - call [ebx + device.access_read_csr] + xor ecx, ecx + call [device.access_read_csr] pop ecx test ax,0x100 jnz .L12 loop .L11 .L12: - DEBUGF 1,"hardware reset\n" + DEBUGF 1,"Starting up device\n" xor ecx, ecx mov eax, 0x0002 - call [ebx + device.access_write_csr] + call [device.access_write_csr] xor ecx, ecx - call [ebx + device.access_read_csr] + call [device.access_read_csr] xor ecx, ecx mov eax, PCNET_CSR_INTEN or PCNET_CSR_START - call [ebx + device.access_write_csr] + call [device.access_write_csr] DEBUGF 1,"PCNET reset complete\n" xor eax, eax +; clear packet/byte counters + lea edi, [device.bytes_tx] + mov ecx, 6 + rep stosd + ret @@ -1164,11 +1065,11 @@ transmit: jl .finish ; packet is too short ; check descriptor - movzx eax, [ebx + device.cur_tx] + movzx eax, [device.cur_tx] imul edi, eax, PCNET_PKT_BUF_SZ shl eax, 4 - add edi, [ebx + device.tx_buffer] - add eax, [ebx + device.tx_ring] + add edi, [device.tx_buffer] + add eax, [device.tx_ring] test byte [eax + buf_head.status + 1], 80h jnz .nospace ; descriptor is free, copy data @@ -1189,16 +1090,22 @@ transmit: ; trigger an immediate send xor ecx, ecx ; CSR0 - call [ebx + device.access_read_csr] + call [device.access_read_csr] or eax, PCNET_CSR_TX - call [ebx + device.access_write_csr] + call [device.access_write_csr] ; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... - inc [ebx + device.cur_tx] - and [ebx + device.cur_tx], 3 + inc [device.cur_tx] + and [device.cur_tx], 3 DEBUGF 2," - Packet Sent! " .finish: +; update statistics + inc [device.packets_tx] + + mov ecx, [esp+8] + add dword [device.bytes_tx], ecx + adc dword [device.bytes_tx + 4], 0 DEBUGF 2," - Done!\n" ret @@ -1218,7 +1125,7 @@ transmit: align 4 int_handler: -; DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO + DEBUGF 1,"IRQ %x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO ; find pointer of device wich made IRQ occur @@ -1227,23 +1134,25 @@ int_handler: test ecx, ecx jz .abort .nextdevice: - mov ebx, dword [esi] - mov edx, [ebx + device.io_addr] ; get IRQ reason + mov ebx, [esi] + DEBUGF 1,"device=%x? ", ebx + set_io 0 push ecx xor ecx, ecx ; CSR0 - call [ebx + device.access_read_csr] + call [device.access_read_csr] ; get IRQ reason pop ecx - test al , al - js .got_it + test ax , ax + jnz .got_it add esi, 4 loop .nextdevice - ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver + ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver .got_it: + DEBUGF 1,"yes, reason=%x ", ax ;------------------------------------------------------- ; Possible reasons: ; initialization done - ignore @@ -1253,22 +1162,22 @@ int_handler: ; N.B. One who wants to handle more than one reason must be ready ; to two or more reasons in one IRQ. xor ecx, ecx - call [ebx + device.access_write_csr] + call [device.access_write_csr] ; Received packet ok? test ax, PCNET_CSR_RINT jz @f .receiver_test_loop: - movzx eax, [ebx + device.cur_rx] + movzx eax, [device.cur_rx] ; and eax, PCNET_RX_RING_MOD_MASK mov edi, eax imul esi, eax, PCNET_PKT_BUF_SZ ; - add esi, [ebx + device.rx_buffer] ; esi now points to rx buffer + add esi, [device.rx_buffer] ; esi now points to rx buffer shl edi, 4 ; desc * 16 (16 is size of one ring entry) - add edi, [ebx + device.rx_ring] ; edi now points to current rx ring entry + add edi, [device.rx_ring] ; edi now points to current rx ring entry mov cx , [edi + buf_head.status] @@ -1294,25 +1203,36 @@ int_handler: push ecx ; for eth_receiver push eax ; +; update statistics + inc [device.packets_rx] + + add dword [device.bytes_rx], ecx + adc dword [device.bytes_rx + 4], 0 + xchg edi, eax - push ecx - shr ecx, 2 - cld + +; copy packet data + shr cx , 1 + jnc .nb + movsb + .nb: + shr cx , 1 + jnc .nw + movsw + .nw: rep movsd - pop ecx - and ecx, 3 - rep movsb ; mov word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG mov word [eax + buf_head.status], PCNET_RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now) - inc [ebx + device.cur_rx] ; update descriptor - and [ebx + device.cur_rx], 3 ; + inc [device.cur_rx] ; update descriptor + and [device.cur_rx], 3 ; + DEBUGF 1,"Inserting packet\n" jmp EthReceiver ; Send the copied packet to kernel .abort: - + DEBUGF 1,"done \n" @@: ret @@ -1331,14 +1251,14 @@ write_mac: ; in: mac pushed onto stack (as 3 words) DEBUGF 1,"Writing MAC: %x-%x-%x-%x-%x-%x",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2 - mov edx, [ebx + device.io_addr] - add dx, 2 + mov edx, [device.io_addr] + add edx, 2 xor eax, eax mov ecx, PCNET_CSR_PAR0 @@: pop ax - call [ebx + device.access_write_csr] + call [device.access_write_csr] DEBUGF 1,"." inc ecx cmp ecx, PCNET_CSR_PAR2 @@ -1354,23 +1274,23 @@ write_mac: ; in: mac pushed onto stack (as 3 words) ;; ;; ;;;;;;;;;;;;;;;;;;;;;; -read_mac: ; T- OK +read_mac: DEBUGF 1,"Reading MAC" - mov edx, [ebx + device.io_addr] - add dx, 6 + mov edx, [device.io_addr] + add edx, 6 @@: dec dx dec dx in ax, dx push ax DEBUGF 1,"." - cmp edx, [ebx + device.io_addr] + cmp edx, [device.io_addr] jg @r DEBUGF 1," %x-%x-%x-%x-%x-%x\n",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2 - lea edi, [ebx + device.mac] + lea edi, [device.mac] pop ax stosw pop ax @@ -1382,26 +1302,28 @@ read_mac: ; T- OK switch_to_wio: + DEBUGF 1,"Switch to WIO\n" - mov [ebx + device.access_read_csr], wio_read_csr - mov [ebx + device.access_write_csr], wio_write_csr - mov [ebx + device.access_read_bcr], wio_read_bcr - mov [ebx + device.access_write_bcr], wio_write_bcr - mov [ebx + device.access_read_rap], wio_read_rap - mov [ebx + device.access_write_rap], wio_write_rap - mov [ebx + device.access_reset], wio_reset + mov [device.access_read_csr], wio_read_csr + mov [device.access_write_csr], wio_write_csr + mov [device.access_read_bcr], wio_read_bcr + mov [device.access_write_bcr], wio_write_bcr + mov [device.access_read_rap], wio_read_rap + mov [device.access_write_rap], wio_write_rap + mov [device.access_reset], wio_reset ret switch_to_dwio: + DEBUGF 1,"Switch to DWIO\n" - mov [ebx + device.access_read_csr], dwio_read_csr - mov [ebx + device.access_write_csr], dwio_write_csr - mov [ebx + device.access_read_bcr], dwio_read_bcr - mov [ebx + device.access_write_bcr], dwio_write_bcr - mov [ebx + device.access_read_rap], dwio_read_rap - mov [ebx + device.access_write_rap], dwio_write_rap - mov [ebx + device.access_reset], dwio_reset + mov [device.access_read_csr], dwio_read_csr + mov [device.access_write_csr], dwio_write_csr + mov [device.access_read_bcr], dwio_read_bcr + mov [device.access_write_bcr], dwio_write_bcr + mov [device.access_read_rap], dwio_read_rap + mov [device.access_write_rap], dwio_write_rap + mov [device.access_reset], dwio_reset ret @@ -1489,7 +1411,6 @@ wio_write_rap: ret - wio_reset: push eax @@ -1501,7 +1422,6 @@ wio_reset: ret - ; ecx - index ; return: ; eax - data @@ -1595,45 +1515,6 @@ dwio_reset: -adjust_pci_device: - ;*******Get current setting************************ - movzx edx, byte [ebx + device.pci_dev] - movzx ecx, byte [ebx + device.pci_bus] - push ecx edx - stdcall PciRead16, ecx ,edx ,0x04 - pop edx ecx -; ;******see if its already set as bus master******** -; and ax,5 -; cmp ax,5 -; je .Latency - ;******Make card a bus master******* - or al, 5 - stdcall PciWrite16, ecx ,edx ,0x04, eax - ;******Check latency setting*********** - .Latency: - ;*******Get current latency setting************************ -; mov al, 1 ;read a byte -; mov bh, [pci_dev] -; mov ah, [pci_bus] -; mov bl, 0x0D ;from Lantency Timer Register -; call pci_read_reg - ;******see if its aat least 64 clocks******** -; cmp ax,64 -; jge PCNET_adjust_pci_device_Done - ;******Set latency to 32 clocks******* -; mov cx, 64 ;value to write -; mov bh, [pci_dev] -; mov al, 1 ;write a byte -; mov ah, [pci_bus] -; mov bl, 0x0D ;to Lantency Timer Register -; call pci_write_reg - ;******Check latency setting*********** - .Done: - ret - - - - ; End of code align 4 ; Place all initialised data here