From 084d99548d37edf736fc3dcfe8c8d581cadffd84 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Thu, 15 Jul 2010 18:54:19 +0000 Subject: [PATCH] -Refactoring of network drivers. -Ommitted unnescessary copying of packets in some drivers. -Some small updates in TCP (perhaps 50% done ?) git-svn-id: svn://kolibrios.org@1519 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/drivers/3c59x.asm | 520 +++--- kernel/branches/net/drivers/RTL8029.asm | 101 +- kernel/branches/net/drivers/RTL8139.asm | 409 ++--- kernel/branches/net/drivers/dec21x4x.asm | 62 +- kernel/branches/net/drivers/i8255x.asm | 1140 ------------ kernel/branches/net/drivers/netdrv.inc | 58 +- kernel/branches/net/drivers/pcnet32.asm | 757 ++++---- kernel/branches/net/drivers/sis900.asm | 2133 ++++++++++------------ kernel/branches/net/network/ARP.inc | 18 +- kernel/branches/net/network/IPv4.inc | 8 +- kernel/branches/net/network/ethernet.inc | 41 +- kernel/branches/net/network/icmp.inc | 41 +- kernel/branches/net/network/socket.inc | 21 +- kernel/branches/net/network/stack.inc | 82 +- kernel/branches/net/network/tcp.inc | 306 +++- kernel/branches/net/network/udp.inc | 4 +- 16 files changed, 2245 insertions(+), 3456 deletions(-) delete mode 100644 kernel/branches/net/drivers/i8255x.asm diff --git a/kernel/branches/net/drivers/3c59x.asm b/kernel/branches/net/drivers/3c59x.asm index ebb8c048fb..f8af83ad42 100644 --- a/kernel/branches/net/drivers/3c59x.asm +++ b/kernel/branches/net/drivers/3c59x.asm @@ -1,22 +1,18 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; +;; 3Com network driver for KolibriOS ;; +;; ;; +;; Ported to KolibriOS net-branch by hidnplayr (28/05/10) ;; +;; ;; +;; Thanks to: scrap metal recyclers, whom provide me with ;; +;; loads of hardware ;; +;; diamond: who makes me understand KolibriOS ;; +;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Ethernet Driver for KolibriOS -;; -;; 3c59x.asm -;; Ported to KolibriOS net-branch by hidnplayr (28/05/10) -;; -;; Thanks to: scrap metal recyclers, whom provide me with loads of hardware -;; diamond: who makes me understand KolibriOS -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; 3C59X.INC ;; @@ -84,13 +80,14 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -PROMISCIOUS equ 1 - - format MS COFF API_VERSION equ 0x01000100 + DRIVER_VERSION equ 5 + + MAX_DEVICES equ 16 + FORCE_FD equ 0 ; forcing full duplex mode makes sense at some cards and link types + PROMISCIOUS equ 0 ; enables promiscous mode DEBUG equ 1 __DEBUG__ equ 1 @@ -101,55 +98,18 @@ include 'imports.inc' include 'fdo.inc' include 'netdrv.inc' - -OS_BASE equ 0 -new_app_base equ 0x60400000 -PROC_BASE equ OS_BASE+0x0080000 - public START public service_proc public version - -virtual at ebx - - device: - - ETH_DEVICE - - .rx_buffer dd ? - .tx_buffer dd ? - .dpd_buffer dd ? - .upd_buffer dd ? - .curr_upd dd ? - .prev_dpd dd ? - - .io_addr dd ? - .pci_bus db ? - .pci_dev db ? - .irq_line db ? - - .prev_tx_frame dd ? - .ver_id db ? - .full_bus_master db ? - .has_hwcksm db ? - .preamble db ? - .dn_list_ptr_cleared db ? - .self_directed_packet rb 20 - - .size = $ - device - -end virtual - - struc DPD { ; Download Packet Descriptor - .next_ptr dd ? - .frame_start_hdr dd ? - .frag_addr dd ? ; for packet data - .frag_len dd ? ; for packet data - .realaddr dd ? - .size = 32 + .next_ptr dd ? + .frame_start_hdr dd ? + .frag_addr dd ? ; for packet data + .frag_len dd ? ; for packet data + .realaddr dd ? + .size = 32 } virtual at 0 @@ -159,12 +119,12 @@ end virtual struc UPD { ; Upload Packet Descriptor - .next_ptr dd ? - .pkt_status dd ? - .frag_addr dd ? - .frag_len dd ? ; for packet data - .realaddr dd ? - .size = 32 + .next_ptr dd ? + .pkt_status dd ? + .frag_addr dd ? + .frag_len dd ? ; for packet data + .realaddr dd ? + .size = 32 } @@ -172,17 +132,11 @@ virtual at 0 upd UPD end virtual - - MAX_DEVICES equ 16 - FORCE_FD equ 0 ; forcing full duplex mode makes sense at some cards and link types - - ; Ethernet frame symbols ETH_ALEN equ 6 ETH_HLEN equ (2*ETH_ALEN+2) ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for ; mininmum 64bytes frame length - ; Registers REG_POWER_MGMT_CTRL equ 0x7c REG_UP_LIST_PTR equ 0x38 @@ -193,9 +147,11 @@ end virtual REG_TX_STATUS equ 0x1b REG_RX_STATUS equ 0x18 REG_TX_DATA equ 0x10 + ; Common window registers REG_INT_STATUS equ 0xe REG_COMMAND equ 0xe + ; Register window 7 REG_MASTER_STATUS equ 0xc REG_POWER_MGMT_EVENT equ 0xc @@ -203,6 +159,7 @@ end virtual REG_VLAN_ETHER_TYPE equ 0x4 REG_VLAN_MASK equ 0x0 REG_MASTER_ADDRESS equ 0x0 + ; Register window 6 REG_BYTES_XMITTED_OK equ 0xc REG_BYTES_RCVD_OK equ 0xa @@ -216,6 +173,7 @@ end virtual REG_MULTIPLE_COLLISIONS equ 0x2 REG_SQE_ERRORS equ 0x1 REG_CARRIER_LOST equ 0x0 + ; Register window 5 REG_INDICATION_ENABLE equ 0xc REG_INTERRUPT_ENABLE equ 0xa @@ -223,6 +181,7 @@ end virtual REG_RX_FILTER equ 0x8 REG_RX_EARLY_THRESH equ 0x6 REG_TX_START_THRESH equ 0x0 + ; Register window 4 REG_UPPER_BYTES_OK equ 0xe REG_BAD_SSD equ 0xc @@ -231,8 +190,10 @@ end virtual REG_NETWORK_DIAGNOSTIC equ 0x6 REG_FIFO_DIAGNOSTIC equ 0x4 REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported + ; Bits in register window 4 BIT_AUTOSELECT equ 24 + ; Register window 3 REG_TX_FREE equ 0xc REG_RX_FREE equ 0xa @@ -240,6 +201,7 @@ end virtual REG_MAC_CONTROL equ 0x6 REG_MAX_PKT_SIZE equ 0x4 REG_INTERNAL_CONFIG equ 0x0 + ; Register window 2 REG_RESET_OPTIONS equ 0xc REG_STATION_MASK_HI equ 0xa @@ -248,6 +210,7 @@ end virtual REG_STATION_ADDRESS_HI equ 0x4 REG_STATION_ADDRESS_MID equ 0x2 REG_STATION_ADDRESS_LO equ 0x0 + ; Register window 1 REG_TRIGGER_BITS equ 0xc REG_SOS_BITS equ 0xa @@ -258,34 +221,42 @@ end virtual REG_SMB_STATUS equ 0x2 REG_SMB_ADDRESS equ 0x1 REG_SMB_FIFO_DATA equ 0x0 + ; Register window 0 REG_EEPROM_DATA equ 0xc REG_EEPROM_COMMAND equ 0xa REG_BIOS_ROM_DATA equ 0x8 REG_BIOS_ROM_ADDR equ 0x4 + ; Physical management bits BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData BIT_MGMT_DATA equ 1 ; MII management data bit BIT_MGMT_CLK equ 0 ; MII management clock + ; MII commands MII_CMD_MASK equ (1111b shl 10) MII_CMD_READ equ (0110b shl 10) MII_CMD_WRITE equ (0101b shl 10) + ; MII registers REG_MII_BMCR equ 0 ; basic mode control register REG_MII_BMSR equ 1 ; basic mode status register REG_MII_ANAR equ 4 ; auto negotiation advertisement register REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register REG_MII_ANER equ 6 ; auto negotiation expansion register + ; MII bits BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete BIT_MII_PREAMBLE_SUPPRESSION equ 6 + ; eeprom bits and commands EEPROM_CMD_READ equ 0x80 EEPROM_BIT_BUSY equ 15 + ; eeprom registers EEPROM_REG_OEM_NODE_ADDR equ 0xa EEPROM_REG_CAPABILITIES equ 0x10 + ; Commands for command register SELECT_REGISTER_WINDOW equ (1 shl 11) @@ -306,7 +277,6 @@ end virtual EXTRA_PREAMBLE equ 0x4000 ; Status - IntLatch equ 0x0001 HostError equ 0x0002 TxComplete equ 0x0004 @@ -315,18 +285,15 @@ end virtual RxEarly equ 0x0020 IntReq equ 0x0040 StatsFull equ 0x0080 - DMADone equ 0x0100 ; 1 shl 8 - DownComplete equ 0x0200 ; 1 shl 9 - UpComplete equ 0x0400 ; 1 shl 10 + DMADone equ 0x0100 + DownComplete equ 0x0200 + UpComplete equ 0x0400 DMAInProgress equ 0x0800 ; 1 shl 11 (DMA controller is still busy) CmdInProgress equ 0x1000 ; 1 shl 12 (EL3_CMD is still busy) - S_5_INTS equ HostError + RxEarly + UpComplete + DownComplete ; + RxComplete + TxComplete + TxAvailable - - + S_5_INTS equ HostError + RxEarly + UpComplete + DownComplete ;+ TxComplete + RxComplete + TxAvailable ; Commands - TotalReset equ 0 shl 11 SelectWindow equ 1 shl 11 StartCoax equ 2 shl 11 @@ -354,29 +321,47 @@ end virtual StatsEnable equ 21 shl 11 StatsDisable equ 22 shl 11 StopCoax equ 23 shl 11 - SetFilterBit equ 25 shl 11} - + SetFilterBit equ 25 shl 11 ; Rx mode bits - RxStation equ 1 RxMulticast equ 2 RxBroadcast equ 4 RxProm equ 8 - ; RX/TX buffers sizes - MAX_ETH_PKT_SIZE equ 1536 ; max packet size NUM_RX_DESC equ 4 ; a power of 2 number NUM_TX_DESC equ 4 ; a power of 2 number - RX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE*NUM_RX_DESC) - TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE*NUM_TX_DESC) MAX_ETH_FRAME_SIZE equ 1520 ; size of ethernet frame + bytes alignment +virtual at ebx + device: + ETH_DEVICE + .dpd_buffer rd (dpd.size*NUM_TX_DESC)/4 + .upd_buffer rd (upd.size*NUM_RX_DESC)/4 + .curr_upd dd ? + .prev_dpd dd ? + + .io_addr dd ? + .pci_bus db ? + .pci_dev db ? + .irq_line db ? + + .prev_tx_frame dd ? + .ver_id db ? + .full_bus_master db ? + .has_hwcksm db ? + .preamble db ? + .dn_list_ptr_cleared db ? + .self_directed_packet rb 20 + + .size = $ - device + +end virtual section '.flat' code readable align 16 @@ -513,21 +498,14 @@ 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 - find_io [device.pci_bus], [device.pci_dev], [device.io_addr] ; We've found the io address, find IRQ now - 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 - allocate_and_clear [device.tx_buffer], (MAX_ETH_FRAME_SIZE*NUM_TX_DESC), .err - allocate_and_clear [device.rx_buffer], (MAX_ETH_FRAME_SIZE*NUM_RX_DESC), .err - allocate_and_clear [device.dpd_buffer], (dpd.size*NUM_TX_DESC), .err - allocate_and_clear [device.upd_buffer], (dpd.size*NUM_RX_DESC), .err - ; Ok, the eth_device structure is ready, let's probe the device call probe ; this function will output in eax test eax, eax @@ -579,8 +557,6 @@ proc service_proc stdcall, ioctl:dword ; todo: reset device into virgin state .err: - stdcall KernelFree, [device.rx_buffer] - stdcall KernelFree, [device.tx_buffer] stdcall KernelFree, ebx @@ -613,7 +589,7 @@ endp ;*************************************************************************** align 4 -probe: ; Tested - ok +probe: DEBUGF 1,"Probing 3com card\n" @@ -671,6 +647,11 @@ probe: ; Tested - ok jnz .boomerang_func mov [device.transmit], vortex_transmit DEBUGF 1,"Device is a vortex type\n" + DEBUGF 1,"I'm sorry but vortex code hasnt been tested yet\n" + DEBUGF 1,"Please contact me on hidnplayr@kolibrios.org\n" + DEBUGF 1,"If you can help me finish it!\n" + or eax, -1 + ret jmp @f .boomerang_func: ; full bus master, so use boomerang functions mov [device.transmit], boomerang_transmit @@ -812,6 +793,9 @@ reset: mov ecx, 6 rep stosd +; Set the mtu, kernel will be able to send now + mov [device.mtu], 1514 + ret @@ -975,13 +959,9 @@ tx_reset: jnz .tx_reset_loop .tx_set_prev: ; init last_dpd - mov eax, [device.dpd_buffer] - add eax, (NUM_TX_DESC-1)*dpd.size + lea eax, [device.dpd_buffer + (NUM_TX_DESC-1)*dpd.size] mov [device.prev_dpd], eax - mov eax, [device.tx_buffer] - add eax, (NUM_TX_DESC-1)*MAX_ETH_FRAME_SIZE - mov [device.prev_tx_frame], eax .tx_enable: ret @@ -1004,59 +984,54 @@ rx_reset: set_io REG_COMMAND mov ax, RxReset or 0x4 out dx, ax + ; wait for RxReset to complete mov ecx, 200000 -.rx_reset_loop: + .loop: in ax, dx test ah, 10000b ; check CmdInProgress dec ecx - jnz .rx_reset_loop + jnz .loop + ; create upd ring + lea eax, [device.upd_buffer] + GetRealAddr + mov edi, eax ; real addr of first descr - mov eax, [device.upd_buffer] - mov [device.curr_upd], eax - call GetPgAddr - mov esi, eax - - mov eax, [device.rx_buffer] - call GetPgAddr - mov edi, eax - - mov edx, [device.upd_buffer] - add edx, (NUM_RX_DESC-1)*upd.size - - mov eax, [device.upd_buffer] - - push ebx - mov ebx, [device.rx_buffer] + lea esi, [device.upd_buffer] ; ptr to first descr + lea edx, [device.upd_buffer + (NUM_RX_DESC-1)*upd.size] ; ptr to last descr mov ecx, NUM_RX_DESC -.upd_loop: - mov [edx + upd.next_ptr], esi ; edx = upd buff - and [eax + upd.pkt_status], 0 ; eax = next upd buff - mov [eax + upd.frag_addr], edi - mov [eax + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) - mov [eax + upd.realaddr], ebx + .upd_loop: + mov [edx + upd.next_ptr], edi - add edi, MAX_ETH_FRAME_SIZE - add ebx, MAX_ETH_FRAME_SIZE + push ecx edx + stdcall KernelAlloc, MAX_ETH_FRAME_SIZE + pop edx ecx + mov [esi + upd.realaddr], eax + call GetPgAddr + mov [esi + upd.frag_addr], eax + and [esi + upd.pkt_status], 0 + mov [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) + + DEBUGF 1,"UPD: lin=%x phys=%x len=%x next ptr=%x\n", [esi+upd.realaddr]:8, [esi+upd.frag_addr]:8, [esi+upd.frag_len]:8, edi + DEBUGF 1,"UPD: cur=%x prev=%x\n", esi, edx + + mov edx, esi add esi, upd.size - mov edx, eax - add eax, upd.size - + add edi, upd.size dec ecx jnz .upd_loop - pop ebx - - mov eax, [device.upd_buffer] - call GetPgAddr + lea eax, [device.upd_buffer] + mov [device.curr_upd], eax + GetRealAddr set_io 0 set_io REG_UP_LIST_PTR out dx, eax -.rx_enable: + .rx_enable: ret @@ -2228,6 +2203,8 @@ vortex_transmit: mov ax, (10100b shl 11) + 1 ; StartDMADown out dx, ax .finish: + call KernelFree + add esp, 4 ret @@ -2245,26 +2222,32 @@ vortex_transmit: align 4 boomerang_transmit: - DEBUGF 1,"Sending packet (boomerang)\n" + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] + mov eax, [esp+4] + DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ + [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ + [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ + [eax+13]:2,[eax+12]:2 cmp dword [esp+8], MAX_ETH_FRAME_SIZE - ja .finish ; packet is too long + jg .fail call check_tx_status + test al, al jnz tx_reset ; calculate descriptor address - mov eax, [device.prev_dpd] - DEBUGF 1,"Previous DPD: %x\n", eax - add eax, dpd.size - mov ecx, [device.dpd_buffer] - add ecx, NUM_TX_DESC*dpd.size - cmp eax, ecx - cmovae eax, [device.dpd_buffer] ; Wrap if needed + mov esi, [device.prev_dpd] + DEBUGF 1,"Previous DPD: %x\n", esi + add esi, dpd.size + lea ecx, [device.dpd_buffer + (NUM_TX_DESC)*dpd.size] + cmp esi, ecx + jl @f + lea esi, [device.dpd_buffer] ; Wrap if needed + @@: + DEBUGF 1,"Found a free DPD: %x\n", esi - DEBUGF 1,"Found a free DPD: %x\n", eax - push eax ; check DnListPtr set_io 0 set_io REG_DN_LIST_PTR @@ -2272,91 +2255,56 @@ boomerang_transmit: ; mark if Dn_List_Ptr is cleared test eax, eax setz [device.dn_list_ptr_cleared] + ; finish if no more free descriptor is available - FIXME! - cmp eax, [esp] - pop eax - jz .finish - - - push eax ;<<<<<<<<<<<<<<<<<<<<<<<<<<<< -; calculate tx_buffer address - mov edi, [device.prev_tx_frame] - DEBUGF 1,"Previous TX frame:: %x\n", edi - add edi, MAX_ETH_FRAME_SIZE - - mov ecx, [device.tx_buffer] - add ecx, NUM_TX_DESC*MAX_ETH_FRAME_SIZE - cmp edi, ecx - cmovae edi, [device.tx_buffer] ; Wrap if needed - - DEBUGF 1,"Found place in TX buffer: %x\n", edi - push edi ;<<<<<<<<<<<<<<<<<<<<<<<<<<<< +; cmp eax, esi +; jz .finish ; update statistics inc [device.packets_tx] - - mov ecx, [esp+8+8] + mov ecx, [esp+8] ; buffer size add dword [device.bytes_tx], ecx adc dword [device.bytes_tx + 4], 0 -; copy packet data - mov esi, [esp+4+8] - DEBUGF 1,"Copying %u bytes from %x to %x\n", ecx, esi, edi - shr cx , 1 - jnc .nb - movsb - .nb: - shr cx , 1 - jnc .nw - movsw - .nw: - rep movsd - ; program DPD - mov eax, [esp] ; Tx buffer address + and [esi+dpd.next_ptr], 0 + mov eax, [esp+4] ; Tx buffer address + mov [esi+dpd.realaddr], eax call GetPgAddr - mov edi, [esp] - and edi, 4096 - 1 - or edi, eax - - mov eax, [esp+4] ; descriptor - DEBUGF 1,"Frag addr is: %x\n", edi - and [eax+dpd.next_ptr], 0 - mov [eax+dpd.frag_addr], edi - - mov ecx, [esp+8+8] ; packet size + mov [esi+dpd.frag_addr], eax + mov ecx, [esp+8] ; packet size or ecx, 0x80000000 ; last fragment - DEBUGF 1,"Frag size + flag is: %x\n", ecx - mov [eax+dpd.frag_len], ecx + mov [esi+dpd.frag_len], ecx + + mov ecx, [esp+8] ; packet size +; or ecx, 0x8000 ; transmission complete notification + + or ecx, 1 shl 31 - mov ecx, [esp+8+8] ; packet size - or ecx, 0x8000 ; transmission complete notification ; test byte [device.has_hwcksm], 0xff ; jz @f -; or ecx, (1 shl 26) ; set AddTcpChecksum +; or ecx, (1 shl 26) ; set AddTcpChecksum ;@@: - DEBUGF 1,"Frag start_hdr + flag is: %x\n", ecx - mov [eax+dpd.frame_start_hdr], ecx + mov [esi+dpd.frame_start_hdr], ecx + DEBUGF 1,"DPD: lin=%x phys=%x len=%x start hdr=%x\n", [esi+dpd.realaddr]:8, [esi+dpd.frag_addr]:8, [esi+dpd.frag_len]:8, [esi+dpd.frame_start_hdr]:8 -; calculate physical address - mov edi, eax - call GetPgAddr - and edi, 4096 - 1 - or eax, edi +; calculate physical address of dpd + mov eax, esi + GetRealAddr cmp [device.dn_list_ptr_cleared], 0 jz .add_to_list - DEBUGF 1,"DN list ptr: %x\n", eax ; write Dn_List_Ptr + DEBUGF 1,"DPD phys addr=%x\n", eax set_io 0 set_io REG_DN_LIST_PTR out dx, eax - jmp .finish_pop -.add_to_list: + jmp .finish + .add_to_list: DEBUGF 1,"Adding To list\n" - + push eax ; DnStall set_io 0 set_io REG_COMMAND @@ -2364,47 +2312,46 @@ boomerang_transmit: out dx, ax ; wait for DnStall to complete - DEBUGF 1,"Waiting for DnStall\n" mov ecx, 6000 -.wait_for_stall: + .wait_for_stall: in ax, dx ; read REG_INT_STATUS test ah, 10000b jz .dnstall_ok dec ecx jnz .wait_for_stall -.dnstall_ok: + .dnstall_ok: DEBUGF 1,"DnStall ok!\n" - mov eax, [esp] ; prev_tx_frame mov ecx, [device.prev_dpd] mov [ecx+dpd.next_ptr], eax set_io 0 set_io REG_DN_LIST_PTR in eax, dx - test eax, eax + pop eax jnz .dnunstall + ; if Dn_List_Ptr has been cleared fill it up DEBUGF 1,"DnList Ptr has been cleared\n" - mov eax, [esp] out dx, eax -.dnunstall: + .dnunstall: ; DnUnStall set_io 0 set_io REG_COMMAND mov ax, ((110b shl 11)+3) out dx, ax -.finish_pop: - pop [device.prev_tx_frame] - pop [device.prev_dpd] - -.finish: + .finish: + mov [device.prev_dpd], esi xor eax, eax - ret + ret 8 + + .fail: + stdcall KernelFree, [esp+4] + ret 8 ;--------------------------------- @@ -2581,7 +2528,9 @@ int_vortex: .read_frame: ; program buffer address to read in - stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into + push ecx + stdcall KernelAlloc, MAX_ETH_FRAME_SIZE + pop ecx test eax, eax jz .finish @@ -2672,14 +2621,13 @@ int_vortex: align 4 int_boomerang: -; DEBUGF 1,"\nIRQ %x Boomerang\n",eax:2 + DEBUGF 1,"\nIRQ %x Boomerang\n",eax:2 ; find pointer of device wich made IRQ occur mov esi, BOOMERANG_LIST mov ecx, [BOOMERANG_DEVICES] -; DEBUGF 1,"Devices: %u\n", ecx test ecx, ecx jz .fail .nextdevice: @@ -2705,7 +2653,6 @@ int_boomerang: .got_it: DEBUGF 1,"Device: %x Status: %x ", ebx, eax - push ax ; disable all INTS @@ -2713,13 +2660,6 @@ int_boomerang: mov ax, SetIntrEnb out dx, ax -;; acknowledge all int sources -; -; mov ax, word [esp] -; and ax, 0xff -; or ax, AckIntr -; out dx, ax - ;-------------------------------------------------------------------------- test word[esp], UpComplete jz .noRX @@ -2730,75 +2670,59 @@ int_boomerang: DEBUGF 1,"UpComplete\n" ; check if packet is uploaded - mov eax, [device.curr_upd] - test byte [eax+upd.pkt_status+1], 0x80 ; upPktComplete + mov esi, [device.curr_upd] + test byte [esi+upd.pkt_status+1], 0x80 ; upPktComplete jz .finish + DEBUGF 1, "Current upd: %x\n", esi ; packet is uploaded check for any error .check_error: - test byte [eax+upd.pkt_status+1], 0x40 ; upError + test byte [esi+upd.pkt_status+1], 0x40 ; upError jz .copy_packet_length DEBUGF 1,"Error in packet\n" - and [eax+upd.pkt_status], 0 ; mark packet as read + and [esi+upd.pkt_status], 0 ; mark packet as read jmp .finish .copy_packet_length: - mov ecx, [eax+upd.pkt_status] + mov ecx, [esi+upd.pkt_status] and ecx, 0x1fff - cmp ecx, MAX_ETH_PKT_SIZE - jbe .copy_packet - and [eax+upd.pkt_status], 0 - jmp .finish - .copy_packet: - DEBUGF 1, " data hw addr:%x\n", [eax+upd.frag_addr] +; cmp ecx, MAX_ETH_PKT_SIZE +; jbe .copy_packet +; and [esi+upd.pkt_status], 0 +; jmp .finish +; .copy_packet: - mov esi, [eax+upd.realaddr] - - push esi ecx - stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into - pop ecx esi - test eax, eax - jz .finish + DEBUGF 1, "Received %u bytes in buffer %x\n", ecx, [esi+upd.realaddr]:8 push dword .loop ;.finish - push ecx eax - mov edi, eax - - DEBUGF 1, " copying %u bytes from %x to %x\n", ecx, esi, edi + push ecx + push [esi+upd.realaddr] ; update statistics inc [device.packets_rx] - add dword [device.bytes_rx], ecx adc dword [device.bytes_rx + 4], 0 -; copy packet data - shr cx , 1 - jnc .nb - movsb - .nb: - shr cx , 1 - jnc .nw - movsw - .nw: - rep movsd +; update UPD (Alloc new buffer for next packet) + stdcall KernelAlloc, MAX_ETH_FRAME_SIZE + mov [esi + upd.realaddr], eax + GetRealAddr + mov [esi + upd.frag_addr], eax + and [esi + upd.pkt_status], 0 + mov [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) - mov eax, [device.curr_upd] - DEBUGF 1, "current upd: %x\n", eax - and [eax + upd.pkt_status], 0 ; clear the ring buffer entry for reuse - mov [eax + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) ;;; - add eax, upd.size - - mov ecx, [device.upd_buffer] - add ecx, (NUM_RX_DESC)*upd.size - - cmp eax, ecx - cmovae eax, [device.upd_buffer] - mov [device.curr_upd], eax - DEBUGF 1, "next upd: %x\n", eax +; Update UPD pointer + add esi, upd.size + lea ecx, [device.upd_buffer+(NUM_RX_DESC)*upd.size] + cmp esi, ecx + jl @f + lea esi, [device.upd_buffer] + @@: + mov [device.curr_upd], esi + DEBUGF 1, "Next upd: %x\n", esi jmp EthReceiver - .loop: + mov ebx, [esp] jmp .receive @@ -2811,14 +2735,38 @@ int_boomerang: in eax, dx test ah, 0x20 ; UpStalled jz .noUpUnStall + + DEBUGF 1, "upUnStalling\n" ; issue upUnStall command set_io REG_COMMAND mov ax, ((11b shl 12)+1) ; upUnStall out dx, ax - DEBUGF 1, "upUnStalling\n" - .noUpUnStall: + ;;;; FIXME: make upunstall work + + .noUpUnStall: .noRX: + test word[esp], DownComplete + jz .noTX + DEBUGF 1, "Downcomplete!\n" + + mov ecx, NUM_TX_DESC + lea esi, [device.dpd_buffer] + .txloop: + test [esi+dpd.frame_start_hdr], 1 shl 31 + jz .maybenext + + and [esi+dpd.frame_start_hdr], 0 + push ecx + stdcall KernelFree, [esi+dpd.realaddr] + pop ecx + + .maybenext: + add esi, dpd.size + dec ecx + jnz .txloop + +.noTX: pop ax set_io 0 @@ -2826,11 +2774,6 @@ int_boomerang: or ax, AckIntr out dx, ax - ; set_io REG_COMMAND - ; mov ax, AckIntr + IntLatch - ; out dx, ax - - set_io REG_INT_STATUS in ax, dx test ax, S_5_INTS @@ -2841,18 +2784,14 @@ int_boomerang: mov ax, SetIntrEnb + S_5_INTS out dx, ax - ret ; End of code - align 4 ; Place all initialised data here - - macro strtbl name, [string] { common @@ -2866,7 +2805,7 @@ forward VORTEX_DEVICES dd 0 BOOMERANG_DEVICES dd 0 -version dd (5 shl 16) or (API_VERSION and 0xFFFF) +version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) my_service db '3C59X',0 ; max 16 chars include zero @@ -3001,7 +2940,6 @@ dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado HW_VERSIONS_SIZE = $ - hw_versions - include_debug_strings ; All data wich FDO uses will be included here section '.data' data readable writable align 16 ; place all uninitialized data place here diff --git a/kernel/branches/net/drivers/RTL8029.asm b/kernel/branches/net/drivers/RTL8029.asm index 03cd00ee08..c4ff4cda63 100644 --- a/kernel/branches/net/drivers/RTL8029.asm +++ b/kernel/branches/net/drivers/RTL8029.asm @@ -1,9 +1,12 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; -;; RTL8029/ne2000 driver for KolibriOS ;; +;; RTL8029/ne2000 driver for KolibriOS ;; +;; ;; +;; based on RTL8029.asm driver for menuetos ;; +;; and realtek8029.asm for SolarOS by Eugen Brasoveanu ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; with help from CleverMouse ;; @@ -11,55 +14,46 @@ ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; -;; current status (september 2009) - UNSTABLE ;; -;; ;; -;; based on RTL8029.asm driver for menuetos ;; -;; and realtek8029.asm for SolarOS by Eugen Brasoveanu ;; -;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;$Revision$ - format MS COFF -API_VERSION equ 0x01000100 + API_VERSION equ 0x01000100 + DRIVER_VERSION equ 5 -DEBUG equ 1 -__DEBUG__ equ 1 -__DEBUG_LEVEL__ equ 1 + MAX_DEVICES equ 16 + + DEBUG equ 1 + __DEBUG__ equ 1 + __DEBUG_LEVEL__ equ 1 include 'proc32.inc' include 'imports.inc' include 'fdo.inc' include 'netdrv.inc' -OS_BASE equ 0 -new_app_base equ 0x60400000 -PROC_BASE equ OS_BASE+0x0080000 - - virtual at ebx - device: + device: - ETH_DEVICE + ETH_DEVICE - .io_addr dd ? - .irq_line db ? - .pci_bus db ? - .pci_dev db ? + .io_addr dd ? + .irq_line db ? + .pci_bus db ? + .pci_dev db ? - .flags db ? - .vendor db ? - .asic_base dw ? - .memsize db ? - .rx_start db ? - .tx_start db ? - .bmem dd ? - .rmem dd ? - .romdata rb 16 + .flags db ? + .vendor db ? + .asic_base dw ? + .memsize db ? + .rx_start db ? + .tx_start db ? + .bmem dd ? + .rmem dd ? + .romdata rb 16 - .size = $ - device + .size = $ - device end virtual @@ -68,8 +62,6 @@ public START public service_proc public version - MAX_DEVICES equ 16 ; Max number of devices this driver may handle - P0_PSTART equ 0x01 P0_PSTOP equ 0x02 P0_BOUND equ 0x03 @@ -234,8 +226,8 @@ proc service_proc stdcall, ioctl:dword ; check if the device is already listed - mov esi, DEVICE_LIST - mov ecx, [DEVICES] + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .firstdevice_pci @@ -269,8 +261,8 @@ proc service_proc stdcall, ioctl:dword .isa: - mov esi, DEVICE_LIST - mov ecx, [DEVICES] + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .firstdevice_isa mov al , [eax+3] @@ -305,9 +297,9 @@ proc service_proc stdcall, ioctl:dword test eax, eax jnz .err ; If an error occured, exit - mov eax, [DEVICES] - mov [DEVICE_LIST+4*eax], ebx - inc [DEVICES] + mov eax, [devices] + mov [device_list+4*eax], ebx + inc [devices] mov [device.type], NET_TYPE_ETH call NetRegDev @@ -346,7 +338,7 @@ endp create_new_struct: - cmp [DEVICES], MAX_DEVICES + cmp [devices], MAX_DEVICES jge .fail push edx @@ -572,7 +564,7 @@ nsr_001: nsr_002: out dx, al -;clear remote bytes count +; clear remote bytes count set_io 0 xor al, al @@ -584,7 +576,7 @@ nsr_002: out dx, al -;initialize Receive configuration register +; initialize Receive configuration register set_io P0_RCR mov al, 0x20 ; monitor mode out dx, al @@ -670,6 +662,9 @@ nsr_002: mov ecx, 6 rep stosd +; Set the mtu, kernel will be able to send now + mov [device.mtu], 1514 + ; Indicate that we have successfully reset the card DEBUGF 2,"Done!\n" @@ -733,10 +728,14 @@ transmit: adc dword [device.bytes_tx + 4], 0 .finish: + call Kernelfree + add esp, 4 xor eax, eax ret .err: + call Kernelfree + add esp, 4 or eax, -1 ret @@ -752,8 +751,8 @@ int_handler: DEBUGF 2,"IRQ %x ",eax:2 ; find pointer of device wich made INT occur - mov esi, DEVICE_LIST - mov ecx, [DEVICES] + mov esi, device_list + mov ecx, [devices] .nextdevice: mov ebx, [esi] @@ -1197,8 +1196,8 @@ epw_005: ; Wait for Remote DMA Complete ;all initialized data place here align 4 -DEVICES dd 0 -version dd (5 shl 16) or (API_VERSION and 0xFFFF) +devices dd 0 +version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) my_service db 'RTL8029/ne2000',0 ;max 16 chars include zero device_1 db 'Realtek 8029',0 @@ -1213,7 +1212,7 @@ include_debug_strings section '.data' data readable writable align 16 ;place all uninitialized data place here -DEVICE_LIST rd MAX_DEVICES +device_list rd MAX_DEVICES diff --git a/kernel/branches/net/drivers/RTL8139.asm b/kernel/branches/net/drivers/RTL8139.asm index 379c6edb6c..323306daab 100644 --- a/kernel/branches/net/drivers/RTL8139.asm +++ b/kernel/branches/net/drivers/RTL8139.asm @@ -3,22 +3,24 @@ ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; -;; Realtek 8139 driver for KolibriOS ;; +;; Realtek 8139 driver for KolibriOS ;; +;; ;; +;; based on RTL8139.asm driver for menuetos ;; +;; and realtek8139.asm for SolarOS by Eugen Brasoveanu ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; ;; -;; 0.1 - x march 2009 ;; -;; 0.2 - 8 november 2009 ;; -;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - format MS COFF API_VERSION equ 0x01000100 + DRIVER_VERSION equ 5 + + MAX_DEVICES equ 16 DEBUG equ 1 __DEBUG__ equ 1 @@ -29,46 +31,10 @@ include 'imports.inc' include 'fdo.inc' include 'netdrv.inc' -OS_BASE equ 0 -new_app_base equ 0x60400000 -PROC_BASE equ OS_BASE+0x0080000 - public START public service_proc public version - -virtual at ebx - - device: - - ETH_DEVICE - - .rx_buffer dd ? - .tx_buffer dd ? - .rx_data_offset dd ? - .io_addr dd ? - .curr_tx_desc db ? - .pci_bus db ? - .pci_dev db ? - .irq_line db ? - .hw_ver_id db ? - - .size = $ - device - -end virtual - - -; RTL8139 specific defines - - MAX_RTL8139 equ 16 ; Max number of devices this driver may handle - TX_TIMEOUT equ 30 ; 300 milliseconds timeout - - PCI_REG_CMD equ 0x04 ; command register - PCI_BIT_PIO equ 0 ; bit0: io space control - PCI_BIT_MMIO equ 1 ; bit1: memory space control - PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master - REG_IDR0 equ 0x00 REG_MAR0 equ 0x08 ; multicast filter register 0 REG_MAR4 equ 0x0c ; multicast filter register 4 @@ -169,8 +135,8 @@ end virtual RX_BUFFER_SIZE equ (8192 shl RBLEN);+16 MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC + NUM_TX_DESC equ 4 - TX_BUF_SIZE equ 4096 ; size of one tx buffer (set to 4kb because of KolibriOS's page size) EE_93C46_REG_ETH_ID equ 7 ; MAC offset EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address @@ -228,6 +194,30 @@ end virtual TSR_CRS equ 1 SHL 31 +virtual at ebx + + device: + + ETH_DEVICE + + .rx_buffer dd ? + .tx_buffer dd ? + .rx_data_offset dd ? + .io_addr dd ? + .curr_tx_desc db ? + .last_tx_desc db ? + .pci_bus db ? + .pci_dev db ? + .irq_line db ? + .hw_ver_id db ? + + .TX_DESC rd NUM_TX_DESC + + .size = $ - device + +end virtual + + section '.flat' code readable align 16 @@ -298,8 +288,8 @@ proc service_proc stdcall, ioctl:dword ; check if the device is already listed - mov esi, RTL8139_LIST - mov ecx, [RTL8139_DEV] + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .firstdevice @@ -315,11 +305,11 @@ proc service_proc stdcall, ioctl:dword ; This device doesnt have its own eth_device structure yet, lets create one .firstdevice: - cmp [RTL8139_DEV], MAX_RTL8139 ; First check if the driver can handle one more card + cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card jge .fail push edx - stdcall KernelAlloc, 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 @@ -355,7 +345,7 @@ proc service_proc stdcall, ioctl:dword allocate_and_clear [device.rx_buffer], (RX_BUFFER_SIZE+MAX_ETH_FRAME_SIZE), .err - allocate_and_clear [device.tx_buffer], (TX_BUF_SIZE*NUM_TX_DESC), .err + ;; allocate_and_clear [device.tx_buffer], (TX_BUF_SIZE*NUM_TX_DESC), .err ; Ok, the eth_device structure is ready, let's probe the device @@ -363,10 +353,9 @@ proc service_proc stdcall, ioctl:dword test eax, eax jnz .err ; If an error occured, exit - mov eax, [RTL8139_DEV] ; Add the device structure to our device list - mov [RTL8139_LIST+4*eax], ebx ; (IRQ handler uses this list to find device) - inc [RTL8139_DEV] ; - + mov eax, [devices] ; Add the device structure to our device list + mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) + inc [devices] ; mov [device.type], NET_TYPE_ETH call NetRegDev @@ -393,7 +382,7 @@ proc service_proc stdcall, ioctl:dword .err: stdcall KernelFree, dword [device.rx_buffer] - stdcall KernelFree, dword [device.tx_buffer] + ;; stdcall KernelFree, dword [device.tx_buffer] stdcall KernelFree, ebx @@ -537,7 +526,7 @@ reset: DEBUGF 1,"\nCould not attach int handler!\n" ; or eax, -1 ; ret - @@: + @@: ; reset chip @@ -613,6 +602,7 @@ reset: mov [device.rx_data_offset], eax mov [device.curr_tx_desc], al + mov [device.last_tx_desc], al ; clear packet/byte counters @@ -625,21 +615,6 @@ reset: set_io REG_MPC out dx , eax -; Set up the 4 Txbuffer descriptors - - set_io REG_TSAD0 - mov eax, [device.tx_buffer] - mov ecx, 4 - .loop: - push eax - call GetPgAddr - DEBUGF 1,"Desc: %x ", eax - out dx , eax - add dx , 4 - pop eax - add eax, TX_BUF_SIZE - loop .loop - ; set RxBuffer address, init RX buffer offset mov eax, [device.rx_buffer] @@ -658,6 +633,9 @@ reset: call read_mac +; Set the mtu, kernel will be able to send now + mov [device.mtu], 1514 + ; Indicate that we have successfully reset the card DEBUGF 2,"Done!\n" @@ -675,7 +653,6 @@ reset: ;; pointer to device structure in ebx ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - align 4 transmit: DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] @@ -686,71 +663,69 @@ transmit: [eax+13]:2,[eax+12]:2 cmp dword [esp+8], MAX_ETH_FRAME_SIZE - jg .finish ; packet is too long + jg .fail cmp dword [esp+8], 60 - jl .finish ; packet is too short + jl .fail -; check descriptor - DEBUGF 1,"Checking descriptor, " +; check if we own the discriptor + set_io 0 movzx ecx, [device.curr_tx_desc] - mov edx, [device.io_addr] - lea edx, [edx+ecx*4+REG_TSD0] + shl ecx, 2 + lea edx, [edx+ecx+REG_TSD0] in ax, dx - test ax, 0x1fff ; or no size given - jz .send_packet - and ax, (1 shl BIT_TOK) or (1 shl BIT_OWN) - cmp ax, (1 shl BIT_TOK) or (1 shl BIT_OWN) - jz .send_packet -; wait for timeout - DEBUGF 1,"Waiting for timeout, " + test ax, (1 shl BIT_OWN) + jz .wait_to_send - push edx ebx ; TODO : rtl8139 internal timer should be used instead - stdcall Sleep, TX_TIMEOUT ; ? What registers does this destroy ? - pop ebx edx + .send_packet: +; Set the buffer address + set_io 0 + lea edx, [edx+ecx+REG_TSAD0] + mov eax, [esp+4] + mov [device.TX_DESC+ecx], eax + GetRealAddr + out dx, eax - in ax, dx - and ax, (1 shl BIT_TOK) or (1 shl BIT_OWN) - cmp ax, (1 shl BIT_TOK) or (1 shl BIT_OWN) - jz .send_packet ; if chip hung, reset it - push dx - call reset ; reset the card - pop dx -.send_packet: - DEBUGF 1,"Sending packet, " - - push edx - movzx eax, [device.curr_tx_desc] ; calculate the current tx_buffer address - mov edx, TX_BUF_SIZE ;MAX_ETH_FRAME_SIZE ; - mul edx ; - mov edi, [device.tx_buffer] ; - add edi, eax ; Store it in edi - pop edx - - mov esi, [esp+4] ; Copy data to that address - mov ecx, [esp+8] ; - shr ecx, 2 ; - rep movsd ; - mov ecx, [esp+8] ; - and ecx, 3 ; - rep movsb ; - - inc [device.packets_tx] ; - mov eax, [esp+8] ; Get packet size in eax +; And the size of the buffer + set_io 0 + lea edx, [edx+ecx+REG_TSD0] + mov eax, [esp+8] +; or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold + out dx , eax +; Update stats + inc [device.packets_tx] add dword [device.bytes_tx], eax adc dword [device.bytes_tx + 4], 0 -; or eax, (ERTXTH shl BIT_ERTXTH) ; Set descriptor size and the early tx treshold into the correct Transmission status register (TSD0, TSD1, TSD2 or TSD3) - out dx , eax ; - -; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... +; get next descriptor inc [device.curr_tx_desc] and [device.curr_tx_desc], 3 - DEBUGF 1," - Packet Sent! " -.finish: - DEBUGF 1," - Done!\n" - ret + DEBUGF 1,"Packet Sent! " + xor eax, eax + ret 8 + + .wait_to_send: + + DEBUGF 1,"Waiting for timeout\n" + + mov esi, 30 + stdcall Sleep + + in ax, dx + test ax, (1 shl BIT_OWN) + jnz .send_packet + + pusha + call reset ; if chip hung, reset it + popa + + jmp .send_packet + + .fail: + DEBUGF 1,"failed!\n" + or eax, -1 + ret 8 @@ -761,16 +736,15 @@ transmit: ;; Interrupt handler ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;; - 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\n", 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 - mov esi, RTL8139_LIST - mov ecx, [RTL8139_DEV] + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .fail .nextdevice: @@ -799,7 +773,6 @@ int_handler: ;---------------------------------------------------- ; Received packet ok? - test ax, ISR_ROK jz @f push ax @@ -836,7 +809,6 @@ int_handler: test eax, eax ; Test if we allocated succesfully jz .abort - mov edi, eax ; Where we will copy too mov esi, [esp] ; The buffer we will copy from @@ -914,60 +886,78 @@ int_handler: ;---------------------------------------------------- ; Transmit error ? - @@: test ax, ISR_TER jz @f - push ax - cmp [device.curr_tx_desc], 4 - jz .notxd - - set_io 0 - movzx ecx, [device.curr_tx_desc] - lea edx, [edx+ecx*4+REG_TSD0] - in eax, dx - - .notxd: - test eax, TSR_TUN - jz .nobun - DEBUGF 2, "TX: FIFO Buffer underrun!\n" - - .nobun: - test eax, TSR_OWC - jz .noowc - DEBUGF 2, "TX: OWC!\n" - - .noowc: - test eax, TSR_TABT - jz .notabt - DEBUGF 2, "TX: TABT!\n" - - .notabt: - test eax, TSR_CRS - jz .nocsl - DEBUGF 2, "TX: Carrier Sense Lost!\n" - - .nocsl: -; test eax, TSR_OWN or TSR_TOK -; jz .nofd -; DEBUGF 1, "TX: Transmit OK (desc: %u)\n", ecx +; push ax +; cmp [device.curr_tx_desc], 4 +; jz .notxd ; -; .nofd: - pop ax +; set_io 0 +; movzx ecx, [device.curr_tx_desc] +; lea edx, [edx+ecx*4+REG_TSD0] +; in eax, dx +; +; .notxd: +; test eax, TSR_TUN +; jz .nobun +; DEBUGF 2, "TX: FIFO Buffer underrun!\n" +; +; .nobun: +; test eax, TSR_OWC +; jz .noowc +; DEBUGF 2, "TX: OWC!\n" +; +; .noowc: +; test eax, TSR_TABT +; jz .notabt +; DEBUGF 2, "TX: TABT!\n" +; +; .notabt: +; test eax, TSR_CRS +; jz .nocsl +; DEBUGF 2, "TX: Carrier Sense Lost!\n" +; +; .nocsl: +; pop ax ;---------------------------------------------------- ; Transmit ok ? - @@: test ax, ISR_TOK jz @f - DEBUGF 1, "TX: Transmit OK (desc: %u)\n", [device.curr_tx_desc]:1 + push ax + mov si, 4 + .txdesloop: + movzx ecx, [device.last_tx_desc] + shl ecx, 2 + + set_io 0 + set_io REG_TSD0 + add edx, ecx + in eax, dx + + test eax, TSR_TOK + jz .notthisone + mov eax, TSR_OWN + out dx , eax + DEBUGF 1,"TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8 + stdcall KernelFree, [device.TX_DESC+ecx] + .notthisone: + + inc [device.last_tx_desc] + and [device.last_tx_desc], 3 + + dec si + jnz .txdesloop + + .done: + pop ax ;---------------------------------------------------- ; Rx buffer overflow ? - @@: test ax, ISR_RXOVW jz @f @@ -975,16 +965,14 @@ int_handler: push ax DEBUGF 2,"RX-buffer overflow!\n" - mov edx, [device.io_addr] - add edx, REG_ISR + set_io 0 + set_io REG_ISR mov ax , ISR_FIFOOVW or ISR_RXOVW out dx , ax pop ax ;---------------------------------------------------- -; Packet underrun? ? - - +; Packet underrun? @@: test ax, ISR_PUN jz @f @@ -993,23 +981,21 @@ int_handler: ;---------------------------------------------------- ; Receive FIFO overflow ? - @@: test ax, ISR_FIFOOVW jz @f push ax - DEBUGF 2,"RX fifo overflox!\n" + DEBUGF 2,"RX fifo overflow!\n" - mov edx, [device.io_addr] - add edx, REG_ISR + set_io 0 + set_io REG_ISR mov ax , ISR_FIFOOVW or ISR_RXOVW out dx , ax pop ax ;---------------------------------------------------- ; Something about Cable changed ? - @@: test ax, ISR_LENCHG jz .fail @@ -1017,11 +1003,7 @@ int_handler: DEBUGF 2,"Cable changed!\n" call cable -; If none of the above events happened, just exit clearing int - .fail: - - DEBUGF 1,"\n" ret @@ -1213,47 +1195,48 @@ read_eeprom: ; End of code +section '.data' data readable writable align 16 ; place all uninitialized data place here align 4 ; Place all initialised data here -RTL8139_DEV dd 0 -version dd (5 shl 16) or (API_VERSION and 0xFFFF) -my_service db 'RTL8139',0 ; max 16 chars include zero +devices dd 0 +version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) +my_service db 'RTL8139',0 ; max 16 chars include zero -device_1 db 'Realtek 8139',0 -device_2 db 'Realtek 8139A',0 -device_3 db 'Realtek 8139B',0 -device_4 db 'Realtek 8139C',0 -device_5 db 'Realtek 8100',0 -device_6 db 'Realtek 8139D',0 -device_7 db 'Realtek 8139CP',0 -device_8 db 'Realtek 8101',0 -device_unknown db 'Unknown RTL8139 clone', 0 +device_1 db 'Realtek 8139',0 +device_2 db 'Realtek 8139A',0 +device_3 db 'Realtek 8139B',0 +device_4 db 'Realtek 8139C',0 +device_5 db 'Realtek 8100',0 +device_6 db 'Realtek 8139D',0 +device_7 db 'Realtek 8139CP',0 +device_8 db 'Realtek 8101',0 +device_unknown db 'Unknown RTL8139 clone', 0 -crosslist dd device_1 - dd device_2 - dd device_3 - dd device_4 - dd device_5 - dd device_6 - dd device_7 - dd device_8 - dd device_unknown +crosslist: + dd device_1 + dd device_2 + dd device_3 + dd device_4 + dd device_5 + dd device_6 + dd device_7 + dd device_8 + dd device_unknown -hw_ver_array db VER_RTL8139 ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with - db VER_RTL8139A - db VER_RTL8139B - db VER_RTL8139C - db VER_RTL8100 - db VER_RTL8139D - db VER_RTL8139CP - db VER_RTL8101 - db 0 +hw_ver_array: ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with + db VER_RTL8139 + db VER_RTL8139A + db VER_RTL8139B + db VER_RTL8139C + db VER_RTL8100 + db VER_RTL8139D + db VER_RTL8139CP + db VER_RTL8101 + db 0 HW_VER_ARRAY_SIZE = $-hw_ver_array include_debug_strings ; All data wich FDO uses will be included here -section '.data' data readable writable align 16 ; place all uninitialized data place here - -RTL8139_LIST rd MAX_RTL8139 ; 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 diff --git a/kernel/branches/net/drivers/dec21x4x.asm b/kernel/branches/net/drivers/dec21x4x.asm index 900d2f3960..43c922ff9e 100644 --- a/kernel/branches/net/drivers/dec21x4x.asm +++ b/kernel/branches/net/drivers/dec21x4x.asm @@ -1,17 +1,15 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; -;; DEC 21x4x driver for KolibriOS ;; +;; DEC 21x4x driver for KolibriOS ;; ;; ;; ;; Based on dec21140.Asm from Solar OS by ;; ;; Eugen Brasoveanu, ;; ;; Ontanu Bogdan Valentin ;; ;; ;; -;; Written by hidnplayr@kolibrios.org ;; -;; ;; -;; 0.1 - 5 june 2010 ;; +;; Written by hidnplayr@kolibrios.org ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; @@ -21,6 +19,9 @@ format MS COFF API_VERSION equ 0x01000100 + DRIVER_VERSION equ 5 + + MAX_DEVICES equ 16 DEBUG equ 1 __DEBUG__ equ 1 @@ -31,42 +32,32 @@ include 'imports.inc' include 'fdo.inc' include 'netdrv.inc' -OS_BASE equ 0 -new_app_base equ 0x60400000 -PROC_BASE equ OS_BASE+0x0080000 - public START public service_proc public version - virtual at ebx device: ETH_DEVICE -; device specific - .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 + .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 db ? - .pci_dev db ? - .irq_line db ? + .io_addr dd ? + .pci_bus db ? + .pci_dev db ? + .irq_line db ? - .size = $ - device + .size = $ - device end virtual - - -MAX_DEVICES equ 16 - ;------------------------------------------- ; configuration registers ;------------------------------------------- @@ -381,7 +372,7 @@ proc service_proc stdcall, ioctl:dword ; check if the device is already listed - mov esi, DEVICE_LIST + mov esi, device_list mov ecx, [devices] test ecx, ecx jz .firstdevice @@ -442,7 +433,7 @@ proc service_proc stdcall, ioctl:dword ; 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 - mov [DEVICE_LIST+4*eax], ebx ; (IRQ handler uses this list to find device) + mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) inc [devices] ; call probe ; this function will output in eax @@ -771,6 +762,9 @@ reset: mov ecx, 6 rep stosd +; Set the mtu, kernel will be able to send now + mov [device.mtu], 1514 + DEBUGF 1,"Reset done\n" ret @@ -1000,15 +994,18 @@ transmit: DEBUGF 1,"transmit ok\n" xor eax, eax + call Kernelfree + add esp, 4 ret .fail: DEBUGF 1,"transmit failed\n" or eax, -1 + call Kernelfree + add esp, 4 ret - ;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Interrupt handler ;; @@ -1025,7 +1022,7 @@ int_handler: mov ecx, [devices] test ecx, ecx jz .fail - mov esi, DEVICE_LIST + mov esi, device_list .nextdevice: mov ebx, dword [esi] @@ -1701,17 +1698,16 @@ mdio_write: ;int phy_id: edx, int location: edi, int value: ax) ; End of code - align 4 ; Place all initialised data here devices dd 0 -version dd (5 shl 16) or (API_VERSION and 0xFFFF) +version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) my_service db 'DEC21X4X',0 ; max 16 chars include zero include_debug_strings ; All data wich FDO uses will be included here section '.data' data readable writable align 16 ; place all uninitialized data place here -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 diff --git a/kernel/branches/net/drivers/i8255x.asm b/kernel/branches/net/drivers/i8255x.asm deleted file mode 100644 index 425f9e72c5..0000000000 --- a/kernel/branches/net/drivers/i8255x.asm +++ /dev/null @@ -1,1140 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;; I8255x (Intel eepro 100) driver for KolibriOS ;; -;; ;; -;; Written by hidnplayr@kolibrios.org ;; -;; ;; -;; v0.0 - march 2009 ;; -;; ;; -;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; -;; ;; -;; current status (september 2009) - INCOMPLETE ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -format MS COFF - - API_VERSION equ 0x01000100 - - DEBUG equ 1 - __DEBUG__ equ 1 - __DEBUG_LEVEL__ equ 1 - -include 'proc32.inc' -include 'imports.inc' -include 'fdo.inc' - -OS_BASE equ 0; -new_app_base equ 0x60400000 -PROC_BASE equ OS_BASE+0x0080000 - -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 - -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 dd ? - .bytes_rx dd ? - .packets_tx dd ? - .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) - .name dd ? -; device specific - .io_addr dd ? - .pci_bus db ? - .pci_dev db ? - .irq_line db ? - .status dw ? ; - .command dw ? ; - .link dd ? ; - .rx_buf_addr dd ? ; - .count dw ? ; - .size dw ? ; - .packet dd ? ; - .eeprom_data rd 16 - - .txfd: - .txfd_status dw ? - .txfd_command dw ? - .txfd_link dd ? - .txfd_tx_desc_addr dd ? - .txfd_count dd ? - .txfd_tx_buf_addr0 dd ? - .txfd_tx_buf_size0 dd ? - .txfd_tx_buf_addr1 dd ? - .txfd_tx_buf_size1 dd ? - - .size_: - -} - -virtual at 0 - device ETH_DEVICE -end virtual - - -lstats: -tx_good_frames: dd 0 -tx_coll16_errs: dd 0 -tx_late_colls: dd 0 -tx_underruns: dd 0 -tx_lost_carrier: dd 0 -tx_deferred: dd 0 -tx_one_colls: dd 0 -tx_multi_colls: dd 0 -tx_total_colls: dd 0 - -rx_good_frames: dd 0 -rx_crc_errs: dd 0 -rx_align_errs: dd 0 -rx_resource_errs: dd 0 -rx_overrun_errs: dd 0 -rx_colls_errs: dd 0 -rx_runt_errs: dd 0 - -done_marker: dd 0 - - -confcmd: - .status: dw 0 - .command: dw 0 - .link: dd 0 - -confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 - db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 - db 0x80, 0x3f, 0x05 - - - MAX_I8255x equ 16 ; Max number of devices this driver may handle - - -; 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 - - - -;/***********************************************************************/ -;/* I82557 related defines */ -;/***********************************************************************/ - -; Serial EEPROM section. -; A "bit" grungy, but we work our way through bit-by-bit :->. -; EEPROM_Ctrl bits. -EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock. -EE_CS equ 0x02 ; EEPROM chip select. -EE_DATA_WRITE equ 0x04 ; EEPROM chip data in. -EE_DATA_READ equ 0x08 ; EEPROM chip data out. -EE_WRITE_0 equ 0x4802 -EE_WRITE_1 equ 0x4806 -EE_ENB equ 0x4802 - - -; The EEPROM commands include the alway-set leading bit. -EE_READ_CMD equ 6 - -; The SCB accepts the following controls for the Tx and Rx units: -CU_START equ 0x0010 -CU_RESUME equ 0x0020 -CU_STATSADDR equ 0x0040 -CU_SHOWSTATS equ 0x0050 ; Dump statistics counters. -CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands. -CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters. - -RX_START equ 0x0001 -RX_RESUME equ 0x0002 -RX_ABORT equ 0x0004 -RX_ADDR_LOAD equ 0x0006 -RX_RESUMENR equ 0x0007 -INT_MASK equ 0x0100 -DRVR_INT equ 0x0200 ; Driver generated interrupt. - - - - - - -section '.flat' code readable align 16 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; proc START ;; -;; ;; -;; (standard driver proc) ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -proc START stdcall, state:dword - - cmp [state], 1 - jne .exit - - .entry: - - DEBUGF 1,"Loading I8255x driver\n" - stdcall RegService, my_service, service_proc - ret - - .fail: - .exit: - xor eax, eax - ret - -endp - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; proc SERVICE_PROC ;; -;; ;; -;; (standard driver proc) ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -align 4 -proc service_proc stdcall, ioctl:dword - - mov edx, [ioctl] - mov eax, [ebx+IOCTL.io_code] - -;------------------------------------------------------ - - cmp eax, 0 ;SRV_GETVERSION - jne @F - - cmp [edx+IOCTL.out_size], 4 - jl .fail - mov eax, [edx+IOCTL.output] - mov [eax], dword API_VERSION - - xor eax, eax - ret - -;------------------------------------------------------ - @@: - cmp eax, 1 ;SRV_HOOK - jne .fail - - mov eax, [esp] - DEBUGF 1,"esp=%x [esp]=%x\n",esp,eax - - cmp [edx + IOCTL.inp_size], 3 ; Data input must be at least 3 bytes - jl .fail - - mov eax, [edx + 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, I8255x_LIST - mov ecx, [I8255x_DEV] - test ecx, ecx - jz .firstdevice - mov eax, [edx+IOCTL.input] ; get the pci bus and device numbers - mov bx , [eax+1] ; - .nextdevice: - DEBUGF 1,"1" - 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 - - loop .nextdevice - -; This device doesnt have its own eth_device structure yet, lets create one - .firstdevice: - cmp [I8255x_DEV], MAX_I8255x ; First check if the driver can handle one more card - jge .fail - - push edx - stdcall KernelAlloc, device.size ; 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) - -; 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], devicename - -; save the pci bus and device numbers - - mov eax, [edx+IOCTL.input] - mov cl , [eax+1] - mov [ebx+device.pci_bus], cl - mov cl , [eax+2] - mov [ebx+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: - -; 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 - - 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 - -; Allocate the Receive buffer - - stdcall KernelAlloc, dword (RX_BUFFER_SIZE+MAX_ETH_FRAME_SIZE) - test eax, eax - jz .err - mov [ebx+device.rx_buffer], eax ; Save the address to it into the device struct - -; Now, Clear the allocated buffer - - cld - mov edi, eax - mov ecx, (RX_BUFFER_SIZE)/4 ; divide by 4 because we are going to use DWORD - xor eax, eax - rep stosd - -; Allocate the Transmit Buffer - - stdcall KernelAlloc, dword (TX_BUFFER_SIZE) - test eax, eax - jz .err - mov [ebx+device.tx_buffer], eax - -; This one needs to be cleared too.. - - mov edi, eax - mov ecx, (TX_BUFFER_SIZE)/4 - xor eax, eax - rep stosd - -; Ok, the eth_device structure is ready, let's probe the device - - call probe ; this function will output in eax - test eax, eax - jnz .err ; If an error occured, exit - - mov eax, [I8255x_DEV] ; Add the device structure to our device list - mov [I8255x_LIST+4*eax], ebx ; (IRQ handler uses this list to find device) - inc [I8255x_DEV] ; - - jmp EthRegDev ; Register the device to kernel (ebx points to device struct) - ; Notice the jump instead of call, it is the same as - ; - ; call EthRegDev - ; ret - ; - ; Also notice that the value EthRegDev returned in eax, will be returned to - ; the caller application - -; 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 - -; If an error occured, remove all allocated data and exit (returning -1 in eax) - - .err: - stdcall KernelFree, dword [ebx+device.rx_buffer] - stdcall KernelFree, dword [ebx+device.tx_buffer] - stdcall KernelFree, ebx - - .fail: - or eax, -1 - ret - -;------------------------------------------------------ -endp - - -;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; -;; ;; -;; Actual Hardware dependent code starts here ;; -;; ;; -;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; - - -unload: - ; TODO: (in this particular order) - ; - ; - Stop the device - ; - Detach int handler - ; - Remove device from local list (RTL8139_LIST) - ; - call unregister function in kernel - ; - Remove all allocated structures and buffers the card used - - or eax,-1 - -ret - -;*************************************************************************** -; Function -; I8255x_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -; -;*************************************************************************** - -probe: - - DEBUGF 1," Probing i8255x device: " - -; enable the device - - movzx eax, byte [ebx+device.pci_bus] - movzx ecx, byte [ebx+device.pci_dev] - stdcall PciRead16, eax ,ecx ,PCI_REG_CMD - - mov cx , ax - or cx , 0x05 - movzx eax, byte [ebx+device.pci_bus] - movzx edx, byte [ebx+device.pci_dev] - stdcall PciWrite16, eax ,edx ,PCI_REG_CMD, ecx - -; do something else TODO - - mov ebx, 0x6000000 - mov ecx, 27 - call do_eeprom_cmd - and eax, 0xffe0000 - cmp eax, 0xffe0000 - je bige - - mov ebx, 0x1800000 - mov ecx, 0x40 - jmp doread - -bige: - mov ebx, 0x6000000 - mov ecx, 0x100 - -doread: - - ; do-eeprom-cmd will destroy all registers - ; we have eesize in ecx - ; read_cmd in ebx - - ; Ignore full eeprom - just load the mac address - mov ecx, 0 - -drlp: - - - push ecx ; save count - push ebx - mov eax, ecx - shl eax, 16 - or ebx, eax - mov ecx, 27 - call do_eeprom_cmd - - pop ebx - pop ecx - - mov edx, ecx - shl edx, 2 - mov esi, eeprom_data - add esi, edx - mov [esi], eax - - inc ecx - cmp ecx, 16 - jne drlp - - ; OK, we have the MAC address. - -;*************************************************************************** -; Function -; I8255x_reset -; Description -; Place the chip (ie, the ethernet card) into a virgin state -; No inputs -; All registers destroyed -; -;*************************************************************************** - -reset: - - ; Now reset the card - - mov edx, [ebx+device.io_addr] - add dx, 8 ; SCBPort - xor eax, eax ; The reset cmd == 0 - out dx, eax - - mov esi, 10 - call delay_ms ; Give the card time to warm up. - - mov eax, lstats - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov eax, 0x0140 ; INT_MASK | CU_STATSADDR - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - - mov eax, 0 - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - ; build rxrd structure - mov ax, 0x0001 - mov [ebx+device.status], ax - mov ax, 0x0000 - mov [rxfd_command], ax - - mov eax, rxfd_status - sub eax, OS_BASE - mov [ebx+device.link], eax - - mov eax, Ether_buffer - sub eax, OS_BASE - mov [ebx+device.rx_buf_addr], eax - - mov ax, 0 - mov [ebx+device.count], ax - - mov ax, 1528 - mov [ebx+device.size], ax - - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - - mov eax, rxfd_status - sub eax, OS_BASE - out dx, eax - - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0101 ; INT_MASK | RX_START - out dx, ax - - call wait_for_cmd_done - - ; start the receiver - - mov ax, 0 - mov [ebx+device.status], ax - - mov ax, 0xc000 - mov [ebx+device.command], ax - - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - - mov eax, rxfd_status - sub eax, OS_BASE - out dx, eax - - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0101 ; INT_MASK | RX_START - out dx, ax - - ; Init TX Stuff - - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - - mov eax, 0 - out dx, eax - - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE - out dx, ax - - call wait_for_cmd_done - - ; Set TX Base address - - ; First, set up confcmd values - - mov ax, 2 - mov [confcmd_command], ax - mov eax, txfd - sub eax, OS_BASE - mov [confcmd_link], eax - - mov ax, 1 - mov [txfd_command], ax ; CmdIASetup - - mov ax, 0 - mov [txfd_status], ax - - mov eax, confcmd - sub eax, OS_BASE - mov [txfd_link], eax - - - - ; ETH_ALEN is 6 bytes - - mov esi, eeprom_data - mov edi, node_addr - mov ecx, 3 - -drp000: - - mov eax, [esi] - mov [edi], al - shr eax, 8 - inc edi - mov [edi], al - inc edi - add esi, 4 - loop drp000 - - ; Hard code your MAC address into node_addr at this point, - ; If you cannot read the MAC address from the eeprom in the previous step. - ; You also have to write the mac address into txfd_tx_desc_addr, rather - ; than taking data from eeprom_data - - mov esi, eeprom_data - mov edi, txfd_tx_desc_addr - mov ecx, 3 - -drp001: - - mov eax, [esi] - mov [edi], al - shr eax, 8 - inc edi - mov [edi], al - inc edi - add esi, 4 - loop drp001 - - mov esi, eeprom_data + (6 * 4) - mov eax, [esi] - shr eax, 8 - and eax, 0x3f - cmp eax, 4 ; DP83840 - je drp002 - cmp eax, 10 ; DP83840A - je drp002 - jmp drp003 - -drp002: - - mov ebx, [esi] - and ebx, 0x1f - push ebx - mov ecx, 23 - call mdio_read - pop ebx - or eax, 0x0422 - mov ecx, 23 - mov edx, eax - call mdio_write - -drp003: - - mov ax, 0x4002 ; Cmdsuspend | CmdConfigure - mov [confcmd_command], ax - mov ax, 0 - mov [confcmd_status], ax - mov eax, txfd - mov [confcmd_link], eax - mov ebx, confcmd_data - mov al, 0x88 ; fifo of 8 each - mov [ebx + 1], al - mov al, 0 - mov [ebx + 4], al - mov al, 0x80 - mov [ebx + 5], al - mov al, 0x48 - mov [ebx + 15], al - mov al, 0x80 - mov [ebx + 19], al - mov al, 0x05 - mov [ebx + 21], al - - mov eax, txfd - sub eax, OS_BASE - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov eax, 0x0110 ; INT_MASK | CU_START - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - -jmp skip - - ; wait for thing to start -drp004: - - mov ax, [txfd_status] - test ax, ax - jz drp004 - -skip: - ; Indicate that we have successfully reset the card - - xor eax, eax - - ret - - -;*************************************************************************** -; Function -; I8255x_transmit -; -; Description -; Transmits a packet of data via the ethernet card -; Pointer to 48 bit destination address in edi -; Type of packet in bx -; size of packet in ecx -; pointer to packet data in esi -; -;*************************************************************************** - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Transmit ;; -;; ;; -;; In: buffer pointer in [esp] ;; -;; size of buffer in [esp+4] ;; -;; pointer to device structure in ebx ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -align 4 -transmit: - - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp],[esp+4] - mov eax, [esp] - DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ - [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ - [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ - [eax+13]:2,[eax+12]:2 - - cmp dword [esp+4], MAX_ETH_FRAME_SIZE - jg .finish ; packet is too long - cmp dword [esp+4], 60 - jl .finish ; packet is too short - -; mov [hdr_type], bx - -; mov eax, [edi] -; mov [hdr_dst_addr], eax -; mov ax, [edi+4] -; mov [hdr_dst_addr+4], ax - -; mov eax, [node_addr] -; mov [hdr_src_addr], eax -; mov ax, [node_addr+4] -; mov [hdr_src_addr+4], ax - - mov edx, [ebx+device.io_addr] - in ax, dx - and ax, 0xfc00 - out dx, ax - - mov [ebx+device.txfd_status], 0 - mov [ebx+device.txfd_command], 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex - lea eax, [ebx+device.txfd] - mov [txfd_link], eax - mov [txfd_count], 0x02208000 - mov eax, txfd_tx_buf_addr0 - call GetPgAddr - mov [txfd_tx_desc_addr], eax - mov eax, hdr - call GetPgAddr - mov [txfd_tx_buf_addr0], eax - mov eax, 14 ; sizeof hdr - mov [txfd_tx_buf_size0], eax - - ; Copy the buffer address and size in -; mov eax, esi -; sub eax, OS_BASE -; mov [txfd_tx_buf_addr1], eax -; mov eax, ecx -; mov [txfd_tx_buf_size1], eax - - mov eax, ebx - call GetPgAddr - add eax, device.txfd - mov edx, [ebx+device.io_addr] - add edx, 4 ; SCBPointer - out dx, eax - - mov ax, 0x0110 ; INT_MASK | CU_START - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - out dx, ax - - call wait_for_cmd_done - - mov edx, [ebx+device.io_addr] - in ax, dx - -I8t_001: - - mov ax, [ebx+device.txfd_status] - cmp ax, 0 - je I8t_001 - - mov edx, [ebx+device.io_addr] - in ax, dx - - .finish: - - ret - - - -;*************************************************************************** -; Function -; I8255x_poll -; -; Description -; Polls the ethernet card for a received packet -; Received data, if any, ends up in Ether_buffer -; -;*************************************************************************** -I8255x_poll: - - mov ax, 0 ; assume no data - mov [eth_rx_data_len], ax - - mov ax, [rxfd_status] - cmp ax, 0 - je i8p_exit - - mov ax, 0 - mov [rxfd_status], ax - - mov ax, 0xc000 - mov [rxfd_command], ax - - mov edx, [io_addr] - add edx, 4 ; SCBPointer - - mov eax, rxfd_status - sub eax, OS_BASE - out dx, eax - - mov edx, [ebx+device.io_addr] - add edx, 2 ; SCBCmd - - mov ax, 0x0101 ; INT_MASK | RX_START - out dx, ax - - call wait_for_cmd_done - - mov esi, rxfd_packet - mov edi, Ether_buffer - mov ecx, 1518 - cld - rep movsb - - mov ax, [rxfd_count] - and ax, 0x3fff - mov [eth_rx_data_len], ax - -i8p_exit: - ret - - - - -;*************************************************************************** -; Function -; wait_for_cmd_done -; -; Description -; waits for the hardware to complete a command -; port address in edx -; -; al destroyed -;*************************************************************************** - -wait_for_cmd_done: - -; mov edx, [ebx + device.io_addr] - - .loop: - in al , dx - test al , al - jnz .loop - - ret - - - -;*************************************************************************** -; Function -; mdio_read -; -; Description -; This probably reads a register in the "physical media interface chip" -; Phy_id in ebx NOW EAX -; location in ecx -; -; Data returned in eax -; -;*************************************************************************** - -mdio_read: - - mov edx, [ebx + device.io_addr] - add edx, 16 ; SCBCtrlMDI - -; mov eax, 0x08000000 -; shl ecx, 16 -; or eax, ecx -; shl ebx, 21 -; or eax, ebx - ; - shl ecx, 16 ; - shl eax, 21 ; - or eax, ecx ; - or eax, 0x08000000 ; - out dx , eax ; - ; -mrlp: - call delay_us - in eax, dx - mov ecx, eax - and ecx, 0x10000000 - jz mrlp - - and eax, 0xffff - ret - - - -;*************************************************************************** -; Function -; mdio_write -; -; Description -; This probably writes a register in the "physical media interface chip" -; Phy_id in ebx NOW EAX -; location in ecx -; data in edx -; Data returned in eax -; -;*************************************************************************** - -mdio_write: - -; mov eax, 0x04000000 -; shl ecx, 16 -; or eax, ecx -; shl ebx, 21 -; or eax, ebx -; or eax, edx - - shl ecx, 16 ; - shl ebx, 21 ; - or eax, ecx ; - or eax, edx ; - or eax, 0x04000000 ; - - mov edx, [ebx + device.io_addr] - add edx, 16 ; SCBCtrlMDI - out dx, eax - -mwlp: - call delay_us - in eax, dx - mov ecx, eax - and ecx, 0x10000000 - jz mwlp - - and eax, 0xffff - ret - - -;*************************************************************************** -; Function -; do_eeprom_cmd -; -; Description -; writes a cmd to the ethernet cards eeprom, by bit bashing -; cmd in ebx NOW EAX -; cmd length in ecx -; return in eax -;*************************************************************************** - -do_eeprom_cmd: - - push eax - mov edx, [ebx + device.io_addr] - add dx, 14 ; the value SCBeeprom - - mov ax, EE_ENB - out dx, ax - call delay_us - - mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK - out dx, ax - call delay_us - - ; dx holds ee_addr - ; ecx holds count - ; eax holds cmd - xor edi, edi ; this will be the receive data - -dec_001: - - mov esi, 1 - - dec ecx - shl esi, cl - inc ecx - and esi, [esp] - mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags.. - cmp esi, 0 - jz dec_002 - mov eax, EE_WRITE_1 - -dec_002: - - out dx, ax - call delay_us - - or ax, EE_SHIFT_CLK - out dx, ax - call delay_us - - shl edi,1 - - in ax, dx - and ax, EE_DATA_READ - cmp ax,0 - jz dec_003 - inc edi - -dec_003: - - loop dec_001 - - mov ax, EE_ENB - out dx, ax - call delay_us - - mov ax, 0x4800 - out dx, ax - call delay_us - - add esp, 4 - mov eax, edi - - ret - - - - - -; End of code - -align 4 ; Place all initialised data here - -I8255x_DEV dd 0 -version dd (5 shl 16) or (API_VERSION and 0xFFFF) -my_service db 'I8255x',0 ; max 16 chars include zero -devicename db 'Intel Etherexpress pro/100',0 - - - -include_debug_strings ; All data wich FDO uses will be included here - -section '.data' data readable writable align 16 ; place all uninitialized data place here - -I8255x_LIST rd I8255x ; This list contains all pointers to device structures the driver is handling - diff --git a/kernel/branches/net/drivers/netdrv.inc b/kernel/branches/net/drivers/netdrv.inc index 4f03952bf9..98e50f0493 100644 --- a/kernel/branches/net/drivers/netdrv.inc +++ b/kernel/branches/net/drivers/netdrv.inc @@ -187,47 +187,49 @@ macro virt_to_dma { ; input is eax } macro NET_DEVICE { - .type dd ? + + .type dd ? ; Type field + .mtu dd ? ; Maximal Transmission Unit + .name dd ? ; Ptr to 0 terminated string + + .unload dd ? ; Ptrs to driver functions + .reset dd ? ; + .transmit dd ? ; + + .bytes_tx dq ? ; Statistics, updated by the driver + .bytes_rx dq ? ; + .packets_tx dd ? ; + .packets_rx dd ? ; + + .end: } ;struc ETH_DEVICE { macro ETH_DEVICE { NET_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 ? + + .set_mode dd ? + .get_mode dd ? + + .set_MAC dd ? + .get_MAC dd ? + + .mode dd ? + .mac dp ? + dp ? ; qword alignment + } macro SLIP_DEVICE { NET_DEVICE -; pointers to procedures - .unload dd ? - .reset dd ? - .transmit dd ? + .set_mode dd ? .get_mode dd ? -; status - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? + .mode dd ? - .name dd ? + } macro GetRealAddr { @@ -235,7 +237,7 @@ macro GetRealAddr { push eax call GetPgAddr and dword [esp], (PAGESIZE - 1) - add eax, dword [esp] + or eax, dword [esp] add esp, 4 } diff --git a/kernel/branches/net/drivers/pcnet32.asm b/kernel/branches/net/drivers/pcnet32.asm index d6d61c7eaa..e200b8ce88 100644 --- a/kernel/branches/net/drivers/pcnet32.asm +++ b/kernel/branches/net/drivers/pcnet32.asm @@ -1,38 +1,34 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; +;; PCnet32 driver for KolibriOS ;; +;; ;; +;; Based on the PCnet32 driver for MenuetOS, by Jarek Pelczar ;; +;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; -;; Status: under construction ;; -;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Revision$ - format MS COFF API_VERSION equ 0x01000100 + DRIVER_VERSION equ 5 + + MAX_DEVICES equ 16 DEBUG equ 1 __DEBUG__ equ 1 __DEBUG_LEVEL__ equ 1 -MAX_PCNET equ 4 -MAX_ETH_FRAME_SIZE equ 1514 include 'proc32.inc' include 'imports.inc' include 'fdo.inc' include 'netdrv.inc' - -OS_BASE equ 0 -new_app_base equ 0x60400000 -PROC_BASE equ OS_BASE+0x0080000 - public START public service_proc public version @@ -44,51 +40,51 @@ virtual at ebx ETH_DEVICE - .rx_buffer dd ? - .tx_buffer dd ? + .rx_buffer dd ? + .tx_buffer dd ? - .io_addr dd ? - .irq_line db ? - .pci_bus db ? - .pci_dev db ? + .io_addr dd ? + .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 ? + .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 (must be 4-aligned) + ; The following fields up to .tx_ring_phys inclusive form + ; initialization block for hardware; do not modify (must be 4-aligned) - .private: - .mode_ dw ? - .tlen_rlen dw ? - .phys_addr dp ? - .reserved dw ? - .filter dq ? - .rx_ring_phys dd ? - .tx_ring_phys dd ? - .rx_ring dd ? - .tx_ring dd ? - .cur_rx db ? - .cur_tx db ? - .dirty_rx dd ? - .dirty_tx dd ? - .tx_full db ? - .options dd ? - .full_duplex db ? - .chip_version dd ? - .mii db ? - .ltint db ? - .dxsuflo db ? - .fset db ? - .fdx db ? + .private: + .mode_ dw ? + .tlen_rlen dw ? + .phys_addr dp ? + .reserved dw ? + .filter dq ? + .rx_ring_phys dd ? + .tx_ring_phys dd ? + .rx_ring dd ? + .tx_ring dd ? + .cur_rx db ? + .cur_tx db ? + .dirty_rx dd ? + .dirty_tx dd ? + .tx_full db ? + .options dd ? + .full_duplex db ? + .chip_version dd ? + .mii db ? + .ltint db ? + .dxsuflo db ? + .fset db ? + .fdx db ? - .size = $ - device + .size = $ - device end virtual @@ -154,255 +150,248 @@ end virtual ; 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 + PORT_AUI equ 0x00 + PORT_10BT equ 0x01 + PORT_GPSI equ 0x02 + PORT_MII equ 0x03 + PORT_PORTSEL equ 0x03 + PORT_ASEL equ 0x04 + PORT_100 equ 0x40 + PORT_FD equ 0x80 - PCNET_PORT_AUI equ 0x00 - PCNET_PORT_10BT equ 0x01 - PCNET_PORT_GPSI equ 0x02 - PCNET_PORT_MII equ 0x03 - PCNET_PORT_PORTSEL equ 0x03 - PCNET_PORT_ASEL equ 0x04 - PCNET_PORT_100 equ 0x40 - PCNET_PORT_FD equ 0x80 + DMA_MASK equ 0xffffffff - PCNET_DMA_MASK equ 0xffffffff + LOG_TX_BUFFERS equ 2 + LOG_RX_BUFFERS equ 2 - PCNET_LOG_TX_BUFFERS equ 2 - PCNET_LOG_RX_BUFFERS equ 2 + TX_RING_SIZE equ 4 + TX_RING_MOD_MASK equ (TX_RING_SIZE-1) + TX_RING_LEN_BITS equ (LOG_TX_BUFFERS shl 12) - PCNET_TX_RING_SIZE equ 4 - PCNET_TX_RING_MOD_MASK equ (PCNET_TX_RING_SIZE-1) - PCNET_TX_RING_LEN_BITS equ (PCNET_LOG_TX_BUFFERS shl 12) + RX_RING_SIZE equ 4 + RX_RING_MOD_MASK equ (RX_RING_SIZE-1) + RX_RING_LEN_BITS equ (LOG_RX_BUFFERS shl 4) - PCNET_RX_RING_SIZE equ 4 - PCNET_RX_RING_MOD_MASK equ (PCNET_RX_RING_SIZE-1) - PCNET_RX_RING_LEN_BITS equ (PCNET_LOG_RX_BUFFERS shl 4) + PKT_BUF_SZ equ 1544 + PKT_BUF_SZ_NEG equ 0xf9f8 - PCNET_PKT_BUF_SZ equ 1544 - PCNET_PKT_BUF_SZ_NEG equ 0xf9f8 - - PCNET_WIO_RDP equ 0x10 - PCNET_WIO_RAP equ 0x12 - PCNET_WIO_RESET equ 0x14 - PCNET_WIO_BDP equ 0x16 - PCNET_DWIO_RDP equ 0x10 - PCNET_DWIO_RAP equ 0x14 - PCNET_DWIO_RESET equ 0x18 - PCNET_DWIO_BDP equ 0x1C - PCNET_TOTAL_SIZE equ 0x20 + WIO_RDP equ 0x10 + WIO_RAP equ 0x12 + WIO_RESET equ 0x14 + WIO_BDP equ 0x16 + DWIO_RDP equ 0x10 + DWIO_RAP equ 0x14 + DWIO_RESET equ 0x18 + DWIO_BDP equ 0x1C + TOTAL_SIZE equ 0x20 ; CSR registers - PCNET_CSR_CSR equ 0x00 - PCNET_CSR_IAB0 equ 0x01 - PCNET_CSR_IAB1 equ 0x02 - PCNET_CSR_IMR equ 0x03 - PCNET_CSR_TFEAT equ 0x04 - PCNET_CSR_EXTCTL1 equ 0x05 - PCNET_CSR_DTBLLEN equ 0x06 - PCNET_CSR_EXTCTL2 equ 0x07 - PCNET_CSR_MAR0 equ 0x08 - PCNET_CSR_MAR1 equ 0x09 - PCNET_CSR_MAR2 equ 0x0A - PCNET_CSR_MAR3 equ 0x0B - PCNET_CSR_PAR0 equ 0x0C - PCNET_CSR_PAR1 equ 0x0D - PCNET_CSR_PAR2 equ 0x0E - PCNET_CSR_MODE equ 0x0F - PCNET_CSR_RXADDR0 equ 0x18 - PCNET_CSR_RXADDR1 equ 0x19 - PCNET_CSR_TXADDR0 equ 0x1E - PCNET_CSR_TXADDR1 equ 0x1F - PCNET_CSR_TXPOLL equ 0x2F - PCNET_CSR_RXPOLL equ 0x31 - PCNET_CSR_RXRINGLEN equ 0x4C - PCNET_CSR_TXRINGLEN equ 0x4E - PCNET_CSR_DMACTL equ 0x50 - PCNET_CSR_BUSTIMER equ 0x52 - PCNET_CSR_MEMERRTIMEO equ 0x64 - PCNET_CSR_ONNOWMISC equ 0x74 - PCNET_CSR_ADVFEAT equ 0x7A - PCNET_CSR_MACCFG equ 0x7D - PCNET_CSR_CHIPID0 equ 0x58 - PCNET_CSR_CHIPID1 equ 0x59 + CSR_CSR equ 0x00 + CSR_IAB0 equ 0x01 + CSR_IAB1 equ 0x02 + CSR_IMR equ 0x03 + CSR_TFEAT equ 0x04 + CSR_EXTCTL1 equ 0x05 + CSR_DTBLLEN equ 0x06 + CSR_EXTCTL2 equ 0x07 + CSR_MAR0 equ 0x08 + CSR_MAR1 equ 0x09 + CSR_MAR2 equ 0x0A + CSR_MAR3 equ 0x0B + CSR_PAR0 equ 0x0C + CSR_PAR1 equ 0x0D + CSR_PAR2 equ 0x0E + CSR_MODE equ 0x0F + CSR_RXADDR0 equ 0x18 + CSR_RXADDR1 equ 0x19 + CSR_TXADDR0 equ 0x1E + CSR_TXADDR1 equ 0x1F + CSR_TXPOLL equ 0x2F + CSR_RXPOLL equ 0x31 + CSR_RXRINGLEN equ 0x4C + CSR_TXRINGLEN equ 0x4E + CSR_DMACTL equ 0x50 + CSR_BUSTIMER equ 0x52 + CSR_MEMERRTIMEO equ 0x64 + CSR_ONNOWMISC equ 0x74 + CSR_ADVFEAT equ 0x7A + CSR_MACCFG equ 0x7D + CSR_CHIPID0 equ 0x58 + CSR_CHIPID1 equ 0x59 ; Control and Status Register (CSR0) - PCNET_CSR_INIT equ 1 shl 0 - PCNET_CSR_START equ 1 shl 1 - PCNET_CSR_STOP equ 1 shl 2 - PCNET_CSR_TX equ 1 shl 3 - PCNET_CSR_TXON equ 1 shl 4 - PCNET_CSR_RXON equ 1 shl 5 - PCNET_CSR_INTEN equ 1 shl 6 - PCNET_CSR_INTR equ 1 shl 7 - PCNET_CSR_IDONE equ 1 shl 8 - PCNET_CSR_TINT equ 1 shl 9 - PCNET_CSR_RINT equ 1 shl 10 - PCNET_CSR_MERR equ 1 shl 11 - PCNET_CSR_MISS equ 1 shl 12 - PCNET_CSR_CERR equ 1 shl 13 + CSR_INIT equ 1 shl 0 + CSR_START equ 1 shl 1 + CSR_STOP equ 1 shl 2 + CSR_TX equ 1 shl 3 + CSR_TXON equ 1 shl 4 + CSR_RXON equ 1 shl 5 + CSR_INTEN equ 1 shl 6 + CSR_INTR equ 1 shl 7 + CSR_IDONE equ 1 shl 8 + CSR_TINT equ 1 shl 9 + CSR_RINT equ 1 shl 10 + CSR_MERR equ 1 shl 11 + CSR_MISS equ 1 shl 12 + CSR_CERR equ 1 shl 13 ; Interrupt masks and deferral control (CSR3) - PCNET_IMR_BSWAP equ 0x0004 - PCNET_IMR_ENMBA equ 0x0008 ; enable modified backoff alg - PCNET_IMR_DXMT2PD equ 0x0010 - PCNET_IMR_LAPPEN equ 0x0020 ; lookahead packet processing enb - PCNET_IMR_DXSUFLO equ 0x0040 ; disable TX stop on underflow - PCNET_IMR_IDONE equ 0x0100 - PCNET_IMR_TINT equ 0x0200 - PCNET_IMR_RINT equ 0x0400 - PCNET_IMR_MERR equ 0x0800 - PCNET_IMR_MISS equ 0x1000 + IMR_BSWAP equ 0x0004 + IMR_ENMBA equ 0x0008 ; enable modified backoff alg + IMR_DXMT2PD equ 0x0010 + IMR_LAPPEN equ 0x0020 ; lookahead packet processing enb + IMR_DXSUFLO equ 0x0040 ; disable TX stop on underflow + IMR_IDONE equ 0x0100 + IMR_TINT equ 0x0200 + IMR_RINT equ 0x0400 + IMR_MERR equ 0x0800 + IMR_MISS equ 0x1000 - PCNET_IMR equ PCNET_IMR_TINT+PCNET_IMR_RINT+PCNET_IMR_IDONE+PCNET_IMR_MERR+PCNET_IMR_MISS + IMR equ IMR_TINT+IMR_RINT+IMR_IDONE+IMR_MERR+IMR_MISS ; Test and features control (CSR4) - PCNET_TFEAT_TXSTRTMASK equ 0x0004 - PCNET_TFEAT_TXSTRT equ 0x0008 - PCNET_TFEAT_RXCCOFLOWM equ 0x0010 ; Rx collision counter oflow - PCNET_TFEAT_RXCCOFLOW equ 0x0020 - PCNET_TFEAT_UINT equ 0x0040 - PCNET_TFEAT_UINTREQ equ 0x0080 - PCNET_TFEAT_MISSOFLOWM equ 0x0100 - PCNET_TFEAT_MISSOFLOW equ 0x0200 - PCNET_TFEAT_STRIP_FCS equ 0x0400 - PCNET_TFEAT_PAD_TX equ 0x0800 - PCNET_TFEAT_TXDPOLL equ 0x1000 - PCNET_TFEAT_DMAPLUS equ 0x4000 + TFEAT_TXSTRTMASK equ 0x0004 + TFEAT_TXSTRT equ 0x0008 + TFEAT_RXCCOFLOWM equ 0x0010 ; Rx collision counter oflow + TFEAT_RXCCOFLOW equ 0x0020 + TFEAT_UINT equ 0x0040 + TFEAT_UINTREQ equ 0x0080 + TFEAT_MISSOFLOWM equ 0x0100 + TFEAT_MISSOFLOW equ 0x0200 + TFEAT_STRIP_FCS equ 0x0400 + TFEAT_PAD_TX equ 0x0800 + TFEAT_TXDPOLL equ 0x1000 + TFEAT_DMAPLUS equ 0x4000 ; Extended control and interrupt 1 (CSR5) - PCNET_EXTCTL1_SPND equ 0x0001 ; suspend - PCNET_EXTCTL1_MPMODE equ 0x0002 ; magic packet mode - PCNET_EXTCTL1_MPENB equ 0x0004 ; magic packet enable - PCNET_EXTCTL1_MPINTEN equ 0x0008 ; magic packet interrupt enable - PCNET_EXTCTL1_MPINT equ 0x0010 ; magic packet interrupt - PCNET_EXTCTL1_MPPLBA equ 0x0020 ; magic packet phys. logical bcast - PCNET_EXTCTL1_EXDEFEN equ 0x0040 ; excessive deferral interrupt enb. - PCNET_EXTCTL1_EXDEF equ 0x0080 ; excessive deferral interrupt - PCNET_EXTCTL1_SINTEN equ 0x0400 ; system interrupt enable - PCNET_EXTCTL1_SINT equ 0x0800 ; system interrupt - PCNET_EXTCTL1_LTINTEN equ 0x4000 ; last TX interrupt enb - PCNET_EXTCTL1_TXOKINTD equ 0x8000 ; TX OK interrupt disable + EXTCTL1_SPND equ 0x0001 ; suspend + EXTCTL1_MPMODE equ 0x0002 ; magic packet mode + EXTCTL1_MPENB equ 0x0004 ; magic packet enable + EXTCTL1_MPINTEN equ 0x0008 ; magic packet interrupt enable + EXTCTL1_MPINT equ 0x0010 ; magic packet interrupt + EXTCTL1_MPPLBA equ 0x0020 ; magic packet phys. logical bcast + EXTCTL1_EXDEFEN equ 0x0040 ; excessive deferral interrupt enb. + EXTCTL1_EXDEF equ 0x0080 ; excessive deferral interrupt + EXTCTL1_SINTEN equ 0x0400 ; system interrupt enable + EXTCTL1_SINT equ 0x0800 ; system interrupt + EXTCTL1_LTINTEN equ 0x4000 ; last TX interrupt enb + EXTCTL1_TXOKINTD equ 0x8000 ; TX OK interrupt disable ; RX/TX descriptor len (CSR6) - PCNET_DTBLLEN_RLEN equ 0x0F00 - PCNET_DTBLLEN_TLEN equ 0xF000 + DTBLLEN_RLEN equ 0x0F00 + DTBLLEN_TLEN equ 0xF000 ; Extended control and interrupt 2 (CSR7) - PCNET_EXTCTL2_MIIPDTINTE equ 0x0001 - PCNET_EXTCTL2_MIIPDTINT equ 0x0002 - PCNET_EXTCTL2_MCCIINTE equ 0x0004 - PCNET_EXTCTL2_MCCIINT equ 0x0008 - PCNET_EXTCTL2_MCCINTE equ 0x0010 - PCNET_EXTCTL2_MCCINT equ 0x0020 - PCNET_EXTCTL2_MAPINTE equ 0x0040 - PCNET_EXTCTL2_MAPINT equ 0x0080 - PCNET_EXTCTL2_MREINTE equ 0x0100 - PCNET_EXTCTL2_MREINT equ 0x0200 - PCNET_EXTCTL2_STINTE equ 0x0400 - PCNET_EXTCTL2_STINT equ 0x0800 - PCNET_EXTCTL2_RXDPOLL equ 0x1000 - PCNET_EXTCTL2_RDMD equ 0x2000 - PCNET_EXTCTL2_RXFRTG equ 0x4000 - PCNET_EXTCTL2_FASTSPNDE equ 0x8000 + EXTCTL2_MIIPDTINTE equ 0x0001 + EXTCTL2_MIIPDTINT equ 0x0002 + EXTCTL2_MCCIINTE equ 0x0004 + EXTCTL2_MCCIINT equ 0x0008 + EXTCTL2_MCCINTE equ 0x0010 + EXTCTL2_MCCINT equ 0x0020 + EXTCTL2_MAPINTE equ 0x0040 + EXTCTL2_MAPINT equ 0x0080 + EXTCTL2_MREINTE equ 0x0100 + EXTCTL2_MREINT equ 0x0200 + EXTCTL2_STINTE equ 0x0400 + EXTCTL2_STINT equ 0x0800 + EXTCTL2_RXDPOLL equ 0x1000 + EXTCTL2_RDMD equ 0x2000 + EXTCTL2_RXFRTG equ 0x4000 + EXTCTL2_FASTSPNDE equ 0x8000 ; Mode (CSR15) - PCNET_MODE_RXD equ 0x0001 ; RX disable - PCNET_MODE_TXD equ 0x0002 ; TX disable - PCNET_MODE_LOOP equ 0x0004 ; loopback enable - PCNET_MODE_TXCRCD equ 0x0008 - PCNET_MODE_FORCECOLL equ 0x0010 - PCNET_MODE_RETRYD equ 0x0020 - PCNET_MODE_INTLOOP equ 0x0040 - PCNET_MODE_PORTSEL equ 0x0180 - PCNET_MODE_RXVPAD equ 0x2000 - PCNET_MODE_RXNOBROAD equ 0x4000 - PCNET_MODE_PROMISC equ 0x8000 + MODE_RXD equ 0x0001 ; RX disable + MODE_TXD equ 0x0002 ; TX disable + MODE_LOOP equ 0x0004 ; loopback enable + MODE_TXCRCD equ 0x0008 + MODE_FORCECOLL equ 0x0010 + MODE_RETRYD equ 0x0020 + MODE_INTLOOP equ 0x0040 + MODE_PORTSEL equ 0x0180 + MODE_RXVPAD equ 0x2000 + MODE_RXNOBROAD equ 0x4000 + MODE_PROMISC equ 0x8000 ; BCR (Bus Control Registers) - PCNET_BCR_MMRA equ 0x00 ; Master Mode Read Active - PCNET_BCR_MMW equ 0x01 ; Master Mode Write Active - PCNET_BCR_MISCCFG equ 0x02 - PCNET_BCR_LED0 equ 0x04 - PCNET_BCR_LED1 equ 0x05 - PCNET_BCR_LED2 equ 0x06 - PCNET_BCR_LED3 equ 0x07 - PCNET_BCR_DUPLEX equ 0x09 - PCNET_BCR_BUSCTL equ 0x12 - PCNET_BCR_EECTL equ 0x13 - PCNET_BCR_SSTYLE equ 0x14 - PCNET_BCR_PCILAT equ 0x16 - PCNET_BCR_PCISUBVENID equ 0x17 - PCNET_BCR_PCISUBSYSID equ 0x18 - PCNET_BCR_SRAMSIZE equ 0x19 - PCNET_BCR_SRAMBOUND equ 0x1A - PCNET_BCR_SRAMCTL equ 0x1B - PCNET_BCR_MIICTL equ 0x20 - PCNET_BCR_MIIADDR equ 0x21 - PCNET_BCR_MIIDATA equ 0x22 - PCNET_BCR_PCIVENID equ 0x23 - PCNET_BCR_PCIPCAP equ 0x24 - PCNET_BCR_DATA0 equ 0x25 - PCNET_BCR_DATA1 equ 0x26 - PCNET_BCR_DATA2 equ 0x27 - PCNET_BCR_DATA3 equ 0x28 - PCNET_BCR_DATA4 equ 0x29 - PCNET_BCR_DATA5 equ 0x2A - PCNET_BCR_DATA6 equ 0x2B - PCNET_BCR_DATA7 equ 0x2C - PCNET_BCR_ONNOWPAT0 equ 0x2D - PCNET_BCR_ONNOWPAT1 equ 0x2E - PCNET_BCR_ONNOWPAT2 equ 0x2F - PCNET_BCR_PHYSEL equ 0x31 + BCR_MMRA equ 0x00 ; Master Mode Read Active + BCR_MMW equ 0x01 ; Master Mode Write Active + BCR_MISCCFG equ 0x02 + BCR_LED0 equ 0x04 + BCR_LED1 equ 0x05 + BCR_LED2 equ 0x06 + BCR_LED3 equ 0x07 + BCR_DUPLEX equ 0x09 + BCR_BUSCTL equ 0x12 + BCR_EECTL equ 0x13 + BCR_SSTYLE equ 0x14 + BCR_PCILAT equ 0x16 + BCR_PCISUBVENID equ 0x17 + BCR_PCISUBSYSID equ 0x18 + BCR_SRAMSIZE equ 0x19 + BCR_SRAMBOUND equ 0x1A + BCR_SRAMCTL equ 0x1B + BCR_MIICTL equ 0x20 + BCR_MIIADDR equ 0x21 + BCR_MIIDATA equ 0x22 + BCR_PCIVENID equ 0x23 + BCR_PCIPCAP equ 0x24 + BCR_DATA0 equ 0x25 + BCR_DATA1 equ 0x26 + BCR_DATA2 equ 0x27 + BCR_DATA3 equ 0x28 + BCR_DATA4 equ 0x29 + BCR_DATA5 equ 0x2A + BCR_DATA6 equ 0x2B + BCR_DATA7 equ 0x2C + BCR_ONNOWPAT0 equ 0x2D + BCR_ONNOWPAT1 equ 0x2E + BCR_ONNOWPAT2 equ 0x2F + BCR_PHYSEL equ 0x31 ; RX status register - PCNET_RXSTAT_BPE equ 0x0080 ; bus parity error - PCNET_RXSTAT_ENP equ 0x0100 ; end of packet - PCNET_RXSTAT_STP equ 0x0200 ; start of packet - PCNET_RXSTAT_BUFF equ 0x0400 ; buffer error - PCNET_RXSTAT_CRC equ 0x0800 ; CRC error - PCNET_RXSTAT_OFLOW equ 0x1000 ; rx overrun - PCNET_RXSTAT_FRAM equ 0x2000 ; framing error - PCNET_RXSTAT_ERR equ 0x4000 ; error summary - PCNET_RXSTAT_OWN equ 0x8000 + RXSTAT_BPE equ 0x0080 ; bus parity error + RXSTAT_ENP equ 0x0100 ; end of packet + RXSTAT_STP equ 0x0200 ; start of packet + RXSTAT_BUFF equ 0x0400 ; buffer error + RXSTAT_CRC equ 0x0800 ; CRC error + RXSTAT_OFLOW equ 0x1000 ; rx overrun + RXSTAT_FRAM equ 0x2000 ; framing error + RXSTAT_ERR equ 0x4000 ; error summary + RXSTAT_OWN equ 0x8000 ; TX status register - PCNET_TXSTAT_TRC equ 0x0000000F ; transmit retries - PCNET_TXSTAT_RTRY equ 0x04000000 ; retry - PCNET_TXSTAT_LCAR equ 0x08000000 ; lost carrier - PCNET_TXSTAT_LCOL equ 0x10000000 ; late collision - PCNET_TXSTAT_EXDEF equ 0x20000000 ; excessive deferrals - PCNET_TXSTAT_UFLOW equ 0x40000000 ; transmit underrun - PCNET_TXSTAT_BUFF equ 0x80000000 ; buffer error - - PCNET_TXCTL_OWN equ 0x80000000 - PCNET_TXCTL_ERR equ 0x40000000 ; error summary - PCNET_TXCTL_ADD_FCS equ 0x20000000 ; add FCS to pkt - PCNET_TXCTL_MORE_LTINT equ 0x10000000 - PCNET_TXCTL_ONE equ 0x08000000 - PCNET_TXCTL_DEF equ 0x04000000 - PCNET_TXCTL_STP equ 0x02000000 - PCNET_TXCTL_ENP equ 0x01000000 - PCNET_TXCTL_BPE equ 0x00800000 - PCNET_TXCTL_MBO equ 0x0000F000 - PCNET_TXCTL_BUFSZ equ 0x00000FFF + TXSTAT_TRC equ 0x0000000F ; transmit retries + TXSTAT_RTRY equ 0x04000000 ; retry + TXSTAT_LCAR equ 0x08000000 ; lost carrier + TXSTAT_LCOL equ 0x10000000 ; late collision + TXSTAT_EXDEF equ 0x20000000 ; excessive deferrals + TXSTAT_UFLOW equ 0x40000000 ; transmit underrun + TXSTAT_BUFF equ 0x80000000 ; buffer error + TXCTL_OWN equ 0x80000000 + TXCTL_ERR equ 0x40000000 ; error summary + TXCTL_ADD_FCS equ 0x20000000 ; add FCS to pkt + TXCTL_MORE_LTINT equ 0x10000000 + TXCTL_ONE equ 0x08000000 + TXCTL_DEF equ 0x04000000 + TXCTL_STP equ 0x02000000 + TXCTL_ENP equ 0x01000000 + TXCTL_BPE equ 0x00800000 + TXCTL_MBO equ 0x0000F000 + TXCTL_BUFSZ equ 0x00000FFF + MAX_ETH_FRAME_SIZE equ 1514 section '.flat' code readable align 16 @@ -474,11 +463,11 @@ proc service_proc stdcall, ioctl:dword ; check if the device is already listed - mov ecx, [PCNET_DEV] + mov ecx, [devices] test ecx, ecx jz .firstdevice - mov esi, PCNET_LIST + mov esi, device_list ; mov eax, [IOCTL.input] ; get the pci bus and device numbers mov ax , [eax+1] ; .nextdevice: @@ -491,7 +480,7 @@ proc service_proc stdcall, ioctl:dword ; This device doesnt have its own eth_device structure yet, lets create one .firstdevice: - cmp [PCNET_DEV], MAX_PCNET ; First check if the driver can handle one more card + cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card jge .fail push edx @@ -529,15 +518,15 @@ proc service_proc stdcall, ioctl:dword 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 - 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_and_clear [device.tx_buffer], (RX_RING_SIZE * PKT_BUF_SZ), .err + allocate_and_clear [device.rx_buffer], (TX_RING_SIZE * PKT_BUF_SZ), .err + allocate_and_clear [device.rx_ring], (RX_RING_SIZE * buf_head.size), .err mov eax, [device.rx_ring] call GetPgAddr mov [device.rx_ring_phys], eax - allocate_and_clear [device.tx_ring], (PCNET_TX_RING_SIZE * buf_head.size), .err + allocate_and_clear [device.tx_ring], (TX_RING_SIZE * buf_head.size), .err mov eax, [device.tx_ring] call GetPgAddr @@ -545,9 +534,9 @@ proc service_proc stdcall, ioctl:dword ; 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, [PCNET_DEV] ; Add the device structure to our device list - mov [PCNET_LIST+4*eax], ebx ; (IRQ handler uses this list to find device) - inc [PCNET_DEV] ; + mov eax, [devices] ; Add the device structure to our device list + mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) + inc [devices] ; call probe ; this function will output in eax test eax, eax @@ -576,11 +565,11 @@ proc service_proc stdcall, ioctl:dword .destroy: ; todo: reset device into virgin state - dec [PCNET_DEV] + dec [devices] .err: DEBUGF 1,"Error, removing all data !\n" stdcall KernelFree, [device.rx_buffer] - stdcall KernelFree, [device.tx_buffer] +;;; stdcall KernelFree, [device.tx_buffer] stdcall KernelFree, ebx .fail: @@ -626,22 +615,22 @@ probe: ; first, fill in some of the structure variables mov edi, [device.rx_ring] - mov ecx, PCNET_RX_RING_SIZE + mov ecx, 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.length], 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 + add eax, 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 ecx, TX_RING_SIZE mov eax, [device.tx_buffer] call GetPgAddr .tx_init: @@ -649,11 +638,11 @@ probe: 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 eax, 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) + mov [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS) ; First, we must try to use Word operations call switch_to_wio @@ -667,12 +656,12 @@ probe: ; Try Word I/O mov ax , 88 - add edx, PCNET_WIO_RAP + add edx, WIO_RAP out dx , ax nop nop in ax , dx - sub edx, PCNET_WIO_RAP + sub edx, WIO_RAP cmp ax , 88 jne .try_dwio @@ -692,7 +681,7 @@ probe: jne .no_dev ; Try Dword I/O - set_io PCNET_DWIO_RAP + set_io DWIO_RAP mov eax, 88 out dx , eax nop @@ -715,11 +704,11 @@ probe: ret .L1: - mov ecx, PCNET_CSR_CHIPID0 + mov ecx, CSR_CHIPID0 call [device.access_read_csr] mov esi, eax - mov ecx, PCNET_CSR_CHIPID1 + mov ecx, CSR_CHIPID1 call [device.access_read_csr] shl eax, 16 or eax, esi @@ -790,7 +779,7 @@ probe: .L8: mov [device.name], device_l8 ; mov [device.fdx], 1 - mov ecx, PCNET_CSR_RXPOLL + mov ecx, CSR_RXPOLL call [device.access_read_bcr] call [device.access_write_bcr] jmp .L10 @@ -803,12 +792,12 @@ probe: cmp [device.fset], 1 jne .L11 - mov ecx, PCNET_BCR_BUSCTL + mov ecx, BCR_BUSCTL call [device.access_read_bcr] or eax, 0x800 call [device.access_write_bcr] - mov ecx, PCNET_CSR_DMACTL + mov ecx, CSR_DMACTL call [device.access_read_csr] ; and eax, 0xc00 ; or eax, 0xc00 @@ -820,16 +809,16 @@ probe: .L11: DEBUGF 1,"PCI done\n" - mov eax, PCNET_PORT_ASEL + mov eax, PORT_ASEL 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 [device.tlen_rlen], word (TX_RING_LEN_BITS or RX_RING_LEN_BITS) mov dword [device.filter], 0 mov dword [device.filter+4], 0 - mov eax, PCNET_IMR - mov ecx, PCNET_CSR_IMR ; Write interrupt mask + mov eax, IMR + mov ecx, CSR_IMR ; Write interrupt mask call [device.access_write_csr] @@ -858,7 +847,7 @@ reset: DEBUGF 1,"Switching to 32-bit mode\n" - mov ecx, PCNET_DWIO_RDP + mov ecx, DWIO_RDP mov eax, 0 call wio_write_csr @@ -867,7 +856,7 @@ reset: ; Lets find out if we are really in 32-bit mode now.. set_io 0 - set_io PCNET_DWIO_RAP + set_io DWIO_RAP mov eax, 88 out dx , eax nop @@ -885,10 +874,10 @@ reset: .yes_dwio: ; set/reset autoselect bit - mov ecx, PCNET_BCR_MISCCFG + mov ecx, BCR_MISCCFG call [device.access_read_bcr] and eax,not 2 - test [device.options], PCNET_PORT_ASEL + test [device.options], PORT_ASEL jz .L1 or eax, 2 .L1: @@ -898,24 +887,24 @@ reset: ; Handle full duplex setting cmp byte [device.full_duplex], 0 je .L2 - mov ecx, PCNET_BCR_DUPLEX + mov ecx, BCR_DUPLEX call [device.access_read_bcr] and eax, not 3 - test [device.options], PCNET_PORT_FD + test [device.options], PORT_FD jz .L3 or eax, 1 - cmp [device.options], PCNET_PORT_FD or PCNET_PORT_AUI + cmp [device.options], PORT_FD or PORT_AUI jne .L4 or eax, 2 jmp .L4 .L3: - test [device.options], PCNET_PORT_ASEL + test [device.options], PORT_ASEL jz .L4 cmp [device.chip_version], 0x2627 jne .L4 or eax, 3 .L4: - mov ecx, PCNET_BCR_DUPLEX + mov ecx, BCR_DUPLEX call [device.access_write_bcr] .L2: @@ -924,33 +913,33 @@ reset: mov ecx, 124 call [device.access_read_csr] mov ecx, [device.options] - and ecx, PCNET_PORT_PORTSEL - cmp ecx, PCNET_PORT_GPSI + and ecx, PORT_PORTSEL + cmp ecx, PORT_GPSI jne .L5 or eax, 0x10 .L5: call [device.access_write_csr] cmp [device.mii], 0 je .L6 - test [device.options], PCNET_PORT_ASEL + test [device.options], PORT_ASEL jnz .L6 - mov ecx, PCNET_BCR_MIICTL + mov ecx, BCR_MIICTL call [device.access_read_bcr] and eax,not 0x38 - test [device.options], PCNET_PORT_FD + test [device.options], PORT_FD jz .L7 or eax, 0x10 .L7: - test [device.options], PCNET_PORT_100 + test [device.options], PORT_100 jz .L8 or eax, 0x08 .L8: call [device.access_write_bcr] jmp .L9 .L6: - test [device.options], PCNET_PORT_ASEL + test [device.options], PORT_ASEL jz .L9 - mov ecx, PCNET_BCR_MIICTL + mov ecx, BCR_MIICTL DEBUGF 1,"ASEL, enable auto-negotiation\n" call [device.access_read_bcr] and eax, not 0x98 @@ -965,7 +954,7 @@ reset: call [device.access_write_csr] .L10: mov eax, [device.options] - and eax, PCNET_PORT_PORTSEL + and eax, PORT_PORTSEL shl eax, 7 mov [device.mode_], ax mov dword [device.filter], -1 @@ -1027,7 +1016,7 @@ reset: call [device.access_read_csr] xor ecx, ecx - mov eax, PCNET_CSR_INTEN or PCNET_CSR_START + mov eax, CSR_INTEN or CSR_START call [device.access_write_csr] DEBUGF 1,"PCNET reset complete\n" @@ -1037,6 +1026,9 @@ reset: mov ecx, 6 rep stosd +; Set the mtu, kernel will be able to send now + mov [device.mtu], 1514 + ret @@ -1068,12 +1060,13 @@ transmit: ; check descriptor movzx eax, [device.cur_tx] - imul edi, eax, PCNET_PKT_BUF_SZ + imul edi, eax, PKT_BUF_SZ shl eax, 4 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 mov esi, [esp+4] mov ecx, [esp+8] @@ -1083,6 +1076,7 @@ transmit: rep movsd mov ecx, edx rep movsb + ; set length mov ecx, [esp+8] neg ecx @@ -1093,7 +1087,7 @@ transmit: ; trigger an immediate send xor ecx, ecx ; CSR0 call [device.access_read_csr] - or eax, PCNET_CSR_TX + or eax, CSR_TX call [device.access_write_csr] ; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... @@ -1109,11 +1103,17 @@ transmit: add dword [device.bytes_tx], ecx adc dword [device.bytes_tx + 4], 0 DEBUGF 2," - Done!\n" + + call Kernelfree + add esp, 4 ret .nospace: DEBUGF 1, 'ERROR: no free transmit descriptors\n' ; todo: maybe somehow notify the kernel about the error? + + call Kernelfree + add esp, 4 ret @@ -1131,8 +1131,8 @@ int_handler: ; find pointer of device wich made IRQ occur - mov esi, PCNET_LIST - mov ecx, [PCNET_DEV] + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .abort .nextdevice: @@ -1167,15 +1167,15 @@ int_handler: call [device.access_write_csr] ; Received packet ok? - test ax, PCNET_CSR_RINT + test ax, CSR_RINT jz @f .receiver_test_loop: movzx eax, [device.cur_rx] -; and eax, PCNET_RX_RING_MOD_MASK +; and eax, RX_RING_MOD_MASK mov edi, eax - imul esi, eax, PCNET_PKT_BUF_SZ ; + imul esi, eax, PKT_BUF_SZ ; add esi, [device.rx_buffer] ; esi now points to rx buffer shl edi, 4 ; desc * 16 (16 is size of one ring entry) @@ -1183,13 +1183,13 @@ int_handler: mov cx , [edi + buf_head.status] - test cx , PCNET_RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do + test cx , RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do jnz .abort - test cx , PCNET_RXSTAT_ENP + test cx , RXSTAT_ENP jz .abort - test cx , PCNET_RXSTAT_STP + test cx , RXSTAT_STP jz .abort movzx ecx, [edi + buf_head.msg_length] ; get packet length in ecx @@ -1224,8 +1224,8 @@ int_handler: .nw: rep movsd -; 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) +; mov word [eax + buf_head.length], PKT_BUF_SZ_NEG + mov word [eax + buf_head.status], RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now) inc [device.cur_rx] ; update descriptor and [device.cur_rx], 3 ; @@ -1257,13 +1257,13 @@ write_mac: ; in: mac pushed onto stack (as 3 words) add edx, 2 xor eax, eax - mov ecx, PCNET_CSR_PAR0 + mov ecx, CSR_PAR0 @@: pop ax call [device.access_write_csr] DEBUGF 1,"." inc ecx - cmp ecx, PCNET_CSR_PAR2 + cmp ecx, CSR_PAR2 jl @r DEBUGF 1,"\n" @@ -1338,13 +1338,13 @@ switch_to_dwio: ; eax - data wio_read_csr: - add edx, PCNET_WIO_RAP + add edx, WIO_RAP mov ax , cx out dx , ax - add edx, PCNET_WIO_RDP - PCNET_WIO_RAP + add edx, WIO_RDP - WIO_RAP in ax , dx and eax, 0xffff - sub edx, PCNET_WIO_RDP + sub edx, WIO_RDP ret @@ -1353,13 +1353,13 @@ wio_read_csr: ; ecx - index wio_write_csr: - add edx, PCNET_WIO_RAP + add edx, WIO_RAP xchg eax, ecx out dx , ax xchg eax, ecx - add edx, PCNET_WIO_RDP - PCNET_WIO_RAP + add edx, WIO_RDP - WIO_RAP out dx , ax - sub edx, PCNET_WIO_RDP + sub edx, WIO_RDP ret @@ -1369,13 +1369,13 @@ wio_write_csr: ; eax - data wio_read_bcr: - add edx, PCNET_WIO_RAP + add edx, WIO_RAP mov ax , cx out dx , ax - add edx, PCNET_WIO_BDP - PCNET_WIO_RAP + add edx, WIO_BDP - WIO_RAP in ax , dx and eax, 0xffff - sub edx, PCNET_WIO_BDP + sub edx, WIO_BDP ret @@ -1384,42 +1384,42 @@ wio_read_bcr: ; ecx - index wio_write_bcr: - add edx, PCNET_WIO_RAP + add edx, WIO_RAP xchg eax, ecx out dx , ax xchg eax, ecx - add edx, PCNET_WIO_BDP - PCNET_WIO_RAP + add edx, WIO_BDP - WIO_RAP out dx , ax - sub edx, PCNET_WIO_BDP + sub edx, WIO_BDP ret wio_read_rap: - add edx, PCNET_WIO_RAP + add edx, WIO_RAP in ax , dx and eax, 0xffff - sub edx, PCNET_WIO_RAP + sub edx, WIO_RAP ret ; eax - val wio_write_rap: - add edx, PCNET_WIO_RAP + add edx, WIO_RAP out dx , ax - sub edx, PCNET_WIO_RAP + sub edx, WIO_RAP ret wio_reset: push eax - add edx, PCNET_WIO_RESET + add edx, WIO_RESET in ax , dx pop eax - sub edx, PCNET_WIO_RESET + sub edx, WIO_RESET ret @@ -1429,13 +1429,13 @@ wio_reset: ; eax - data dwio_read_csr: - add edx, PCNET_DWIO_RAP + add edx, DWIO_RAP mov eax, ecx out dx , eax - add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP + add edx, DWIO_RDP - DWIO_RAP in eax, dx and eax, 0xffff - sub edx, PCNET_DWIO_RDP + sub edx, DWIO_RDP ret @@ -1444,13 +1444,13 @@ dwio_read_csr: ; eax - data dwio_write_csr: - add edx, PCNET_DWIO_RAP + add edx, DWIO_RAP xchg eax, ecx out dx , eax - add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP + add edx, DWIO_RDP - DWIO_RAP xchg eax, ecx out dx , eax - sub edx, PCNET_DWIO_RDP + sub edx, DWIO_RDP ret @@ -1459,13 +1459,13 @@ dwio_write_csr: ; eax - data dwio_read_bcr: - add edx, PCNET_DWIO_RAP + add edx, DWIO_RAP mov eax, ecx out dx , eax - add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP + add edx, DWIO_BDP - DWIO_RAP in eax, dx and eax, 0xffff - sub edx, PCNET_DWIO_BDP + sub edx, DWIO_BDP ret @@ -1474,23 +1474,23 @@ dwio_read_bcr: ; eax - data dwio_write_bcr: - add edx, PCNET_DWIO_RAP + add edx, DWIO_RAP xchg eax, ecx out dx , eax - add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP + add edx, DWIO_BDP - DWIO_RAP xchg eax, ecx out dx , eax - sub edx, PCNET_DWIO_BDP + sub edx, DWIO_BDP ret dwio_read_rap: - add edx, PCNET_DWIO_RAP + add edx, DWIO_RAP in eax, dx and eax, 0xffff - sub edx, PCNET_DWIO_RAP + sub edx, DWIO_RAP ret @@ -1498,9 +1498,9 @@ dwio_read_rap: ; eax - val dwio_write_rap: - add edx, PCNET_DWIO_RAP + add edx, DWIO_RAP out dx , eax - sub edx, PCNET_DWIO_RAP + sub edx, DWIO_RAP ret @@ -1508,22 +1508,21 @@ dwio_write_rap: dwio_reset: push eax - add edx, PCNET_DWIO_RESET + add edx, DWIO_RESET in eax, dx pop eax - sub edx, PCNET_DWIO_RESET + sub edx, DWIO_RESET ret ; End of code +align 4 ; Place all initialised data here -align 4 ; Place all initialised data here - -PCNET_DEV dd 0 -version dd (5 shl 16) or (API_VERSION and 0xFFFF) -my_service db 'PCnet',0 ; max 16 chars include zero +devices dd 0 +version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) +my_service db 'PCnet32',0 ; max 16 chars include zero device_l2 db "PCnet/PCI 79C970",0 device_l4 db "PCnet/PCI II 79C970A",0 @@ -1534,25 +1533,25 @@ device_l8 db "PCnet/Home 79C978",0 device_l9 db "PCnet/FAST III 79C975",0 options_mapping: -dd PCNET_PORT_ASEL ; 0 Auto-select -dd PCNET_PORT_AUI ; 1 BNC/AUI -dd PCNET_PORT_AUI ; 2 AUI/BNC -dd PCNET_PORT_ASEL ; 3 not supported -dd PCNET_PORT_10BT or PCNET_PORT_FD ; 4 10baseT-FD -dd PCNET_PORT_ASEL ; 5 not supported -dd PCNET_PORT_ASEL ; 6 not supported -dd PCNET_PORT_ASEL ; 7 not supported -dd PCNET_PORT_ASEL ; 8 not supported -dd PCNET_PORT_MII ; 9 MII 10baseT -dd PCNET_PORT_MII or PCNET_PORT_FD ; 10 MII 10baseT-FD -dd PCNET_PORT_MII ; 11 MII (autosel) -dd PCNET_PORT_10BT ; 12 10BaseT -dd PCNET_PORT_MII or PCNET_PORT_100 ; 13 MII 100BaseTx -dd PCNET_PORT_MII or PCNET_PORT_100 or PCNET_PORT_FD ; 14 MII 100BaseTx-FD -dd PCNET_PORT_ASEL ; 15 not supported +dd PORT_ASEL ; 0 Auto-select +dd PORT_AUI ; 1 BNC/AUI +dd PORT_AUI ; 2 AUI/BNC +dd PORT_ASEL ; 3 not supported +dd PORT_10BT or PORT_FD ; 4 10baseT-FD +dd PORT_ASEL ; 5 not supported +dd PORT_ASEL ; 6 not supported +dd PORT_ASEL ; 7 not supported +dd PORT_ASEL ; 8 not supported +dd PORT_MII ; 9 MII 10baseT +dd PORT_MII or PORT_FD ; 10 MII 10baseT-FD +dd PORT_MII ; 11 MII (autosel) +dd PORT_10BT ; 12 10BaseT +dd PORT_MII or PORT_100 ; 13 MII 100BaseTx +dd PORT_MII or PORT_100 or PORT_FD ; 14 MII 100BaseTx-FD +dd PORT_ASEL ; 15 not supported include_debug_strings ; All data wich FDO uses will be included here section '.data' data readable writable align 16 ; place all uninitialized data place here -PCNET_LIST rd MAX_PCNET ; 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 diff --git a/kernel/branches/net/drivers/sis900.asm b/kernel/branches/net/drivers/sis900.asm index 2449ca74fb..f818390230 100644 --- a/kernel/branches/net/drivers/sis900.asm +++ b/kernel/branches/net/drivers/sis900.asm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Ethernet driver for KolibriOS ;; @@ -23,11 +23,12 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Revision$ - format MS COFF API_VERSION equ 0x01000100 + DRIVER_VERSION equ 5 + + MAX_DEVICES equ 16 DEBUG equ 1 __DEBUG__ equ 1 @@ -41,50 +42,53 @@ include 'netdrv.inc' public START public version -NUM_RX_DESC equ 4 ;* Number of RX descriptors * -NUM_TX_DESC equ 1 ;* Number of TX descriptors * -RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * -TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * -MAX_ETH_FRAME_SIZE equ 1516 +NUM_RX_DESC equ 4 ;* Number of RX descriptors * +NUM_TX_DESC equ 1 ;* Number of TX descriptors * +RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * +TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * +MAX_ETH_FRAME_SIZE equ 1516 -TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ - -virtual at 0 +virtual at ebx device: ETH_DEVICE -; device specific - .io_addr dd ? - .pci_bus db ? - .pci_dev db ? - .irq_line db ? - .cur_rx db ? - .pci_revision db ? - .table_entries: db ? -align 4 - .special_func: dd 0 - .txd: times (3 * NUM_TX_DESC) dd 0 - .rxd: times (3 * NUM_RX_DESC) dd 0 - .size: + .io_addr dd ? + .pci_bus db ? + .pci_dev db ? + .irq_line db ? + .cur_rx db ? + .cur_tx db ? + .last_tx db ? + .pci_revision db ? + .table_entries db ? + + dw ? ; align 4 + + .special_func dd ? + + .txd rd (4 * NUM_TX_DESC) + .rxd rd (4 * NUM_RX_DESC) + + .size = $ - device + end virtual -; First page is designated to ETH_DEVICE, buffers start from second -ALLOCATION_SIZE = ((device.size+0FFFh) and not 0FFFh) + TOTAL_BUFFERS_SIZE -; Note that buffers must be contiguous in the physical memory; -; because KernelAlloc allocates contiguous physical pages only in 8-pages blocks, -; align ALLOCATION_SIZE up to 8*(page size) = 8000h -ALLOCATION_SIZE = (ALLOCATION_SIZE + 7FFFh) and not 7FFFh +macro ee_delay { + push eax + in eax, dx + in eax, dx + in eax, dx + in eax, dx + in eax, dx + in eax, dx + in eax, dx + in eax, dx + in eax, dx + in eax, dx + pop eax +} -MAX_DEVICES = 16 ; maximum number of devices which this driver can handle - - - 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 section '.flat' code readable align 16 @@ -106,15 +110,15 @@ service_proc: ; pointer to IOCTL structure. mov edx, [esp+4] ; edx -> IOCTL ; 2. Get request code and select a handler for the code. - mov eax, [edx+IOCTL.io_code] + mov eax, [IOCTL.io_code] test eax, eax ; check for SRV_GETVERSION jnz @f ; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION. ; 3a. Output size must be at least 4 bytes. - cmp [edx+IOCTL.out_size], 4 + cmp [IOCTL.out_size], 4 jl .fail ; 3b. Write result to the output buffer. - mov eax, [edx+IOCTL.output] + mov eax, [IOCTL.output] mov [eax], dword API_VERSION ; 3c. Return success. xor eax, eax @@ -125,10 +129,10 @@ service_proc: ; 4. This is SRV_HOOK request, input defines the device to hook, no output. ; 4a. The driver works only with PCI devices, ; so input must be at least 3 bytes long. - cmp [edx + IOCTL.inp_size], 3 + cmp [IOCTL.inp_size], 3 jl .fail ; 4b. First byte of input is bus type, 1 stands for PCI. - mov eax, [edx + IOCTL.input] + mov eax, [IOCTL.input] cmp byte [eax], 1 jne .fail ; 4c. Second and third bytes of the input define the device: bus and dev. @@ -136,77 +140,65 @@ service_proc: mov bx, [eax+1] ; 4d. Check if the device was already hooked, ; scan through the list of known devices. - mov esi, DEV_LIST - mov ecx, [NUM_DEV] +; check if the device is already listed + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .firstdevice + +; mov eax, [IOCTL.input] ; get the pci bus and device numbers + mov ax , [eax+1] ; .nextdevice: - lodsd - cmp bx, word [eax + device.pci_bus] - je .find_devicenum + 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 ; 4e. This device doesn't have its own eth_device structure yet, let's create one .firstdevice: ; 4f. Check that we have place for new device. - cmp [NUM_DEV], MAX_DEVICES + cmp [devices], MAX_DEVICES jge .fail ; 4g. Allocate memory for device descriptor and receive+transmit buffers. - stdcall KernelAlloc, ALLOCATION_SIZE + stdcall KernelAlloc, device.size test eax, eax jz .fail ; 4h. Zero the structure. - push eax mov edi, eax mov ecx, (device.size + 3) shr 2 xor eax, eax rep stosd - pop eax -; 4i. Save PCI coordinates, loaded to bx at 4c. - mov word [eax+device.pci_bus], bx - mov ebx, eax ; ebx is always used as a pointer to the structure (in driver, but also in kernel code) +; 4i. Save PCI coordinates + mov eax, [IOCTL.input] + mov cl , [eax+1] + mov [device.pci_bus], cl + mov cl , [eax+2] + mov [device.pci_dev], cl ; 4j. Fill in the direct call addresses into the struct. -; Note that get_MAC pointer is filled in initialization by SIS900_probe. - mov dword [ebx+device.reset], sis900_init - 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 +; Note that get_MAC pointer is filled in initialization by probe. + mov [device.reset], init + 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 ; 4k. 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: - push edx - stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], edx - pop edx - test al, PCI_BASE_ADDRESS_SPACE_IO - jz .inc_reg - and eax, PCI_BASE_ADDRESS_IO_MASK - jnz .got_io +; Now, it's time to find the base io addres of the PCI device + find_io [device.pci_bus], [device.pci_dev], [device.io_addr] - .inc_reg: - add edx, 4 - cmp edx, PCI_BASE_ADDRESS_5 - jbe .reg_check - jmp .fail - - .got_io: - mov [ebx+device.io_addr], eax - -; 4l. We've found the io address, find IRQ now - stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x3c - 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] ; 4m. Add new device to the list (required for int_handler). - mov eax, [NUM_DEV] - mov [DEV_LIST+4*eax], ebx - inc [NUM_DEV] + mov eax, [devices] + mov [device_list+4*eax], ebx + inc [devices] ; 4m. Ok, the eth_device structure is ready, let's probe the device - - call SIS900_probe + call probe test eax, eax jnz .destroy ; 4n. If device was successfully initialized, register it for the kernel. @@ -231,7 +223,7 @@ service_proc: ; If an error occured, remove all allocated data and exit (returning -1 in eax) .destroy: - dec [NUM_DEV] + dec [devices] ; todo: reset device into virgin state .err: @@ -262,14 +254,6 @@ unload: ret -;******************************************************************** -; Interface -; SIS900_reset -; SIS900_probe -; SIS900_poll -; SIS900_transmit -; -;******************************************************************** ;******************************************************************** ; Comments: ; Known to work with the following SIS900 ethernet cards: @@ -283,942 +267,972 @@ ret ; ToDo: ; - Enable MII interface for reading speed ; and duplex settings. -; -; - Update Poll routine to support packet fragmentation. -; +; - Update receive routine to support packet fragmentation. ; - Add additional support for other sis900 based cards ; ;******************************************************************** -; comment the next line out if you don't want debug info printed -; on the debug board. This option adds a lot of bytes to the driver -; so it's worth to comment it out. -; SIS900_DEBUG equ 1 + ETH_ALEN equ 6 ; Size of Ethernet address + ETH_HLEN equ 14 ; Size of ethernet header + ETH_ZLEN equ 60 ; Minimum packet length + DSIZE equ 0x00000fff + CRC_SIZE equ 4 + RFADDR_shift equ 16 + +; Symbolic offsets to registers. + cr equ 0x0 ; Command Register + cfg equ 0x4 ; Configuration Register + mear equ 0x8 ; EEPROM Access Register + ptscr equ 0xc ; PCI Test Control Register + isr equ 0x10 ; Interrupt Status Register + imr equ 0x14 ; Interrupt Mask Register + ier equ 0x18 ; Interrupt Enable Register + epar equ 0x18 ; Enhanced PHY Access Register + txdp equ 0x20 ; Transmit Descriptor Pointer Register + txcfg equ 0x24 ; Transmit Configuration Register + rxdp equ 0x30 ; Receive Descriptor Pointer Register + rxcfg equ 0x34 ; Receive Configuration Register + flctrl equ 0x38 ; Flow Control Register + rxlen equ 0x3c ; Receive Packet Length Register + rfcr equ 0x48 ; Receive Filter Control Register + rfdr equ 0x4C ; Receive Filter Data Register + pmctrl equ 0xB0 ; Power Management Control Register + pmer equ 0xB4 ; Power Management Wake-up Event Register + +; Command Register Bits + RELOAD equ 0x00000400 + ACCESSMODE equ 0x00000200 + RESET equ 0x00000100 + SWI equ 0x00000080 + RxRESET equ 0x00000020 + TxRESET equ 0x00000010 + RxDIS equ 0x00000008 + RxENA equ 0x00000004 + TxDIS equ 0x00000002 + TxENA equ 0x00000001 + +; Configuration Register Bits + DESCRFMT equ 0x00000100 ; 7016 specific + REQALG equ 0x00000080 + SB equ 0x00000040 + POW equ 0x00000020 + EXD equ 0x00000010 + PESEL equ 0x00000008 + LPM equ 0x00000004 + BEM equ 0x00000001 + RND_CNT equ 0x00000400 + FAIR_BACKOFF equ 0x00000200 + EDB_MASTER_EN equ 0x00002000 + +; Eeprom Access Reigster Bits + MDC equ 0x00000040 + MDDIR equ 0x00000020 + MDIO equ 0x00000010 ; 7016 specific + EECS equ 0x00000008 + EECLK equ 0x00000004 + EEDO equ 0x00000002 + EEDI equ 0x00000001 + +; TX Configuration Register Bits + ATP equ 0x10000000 ;Automatic Transmit Padding + MLB equ 0x20000000 ;Mac Loopback Enable + HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) + CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du + +; RX Configuration Register Bits + AJAB equ 0x08000000 ; + ATX equ 0x10000000 ;Accept Transmit Packets + ARP equ 0x40000000 ;accept runt packets (<64bytes) + AEP equ 0x80000000 ;accept error packets + +; Interrupt Reigster Bits + WKEVT equ 0x10000000 + TxPAUSEEND equ 0x08000000 + TxPAUSE equ 0x04000000 + TxRCMP equ 0x02000000 + RxRCMP equ 0x01000000 + DPERR equ 0x00800000 + SSERR equ 0x00400000 + RMABT equ 0x00200000 + RTABT equ 0x00100000 + RxSOVR equ 0x00010000 + HIBERR equ 0x00008000 + SWINT equ 0x00001000 + MIBINT equ 0x00000800 + TxURN equ 0x00000400 + TxIDLE equ 0x00000200 + TxERR equ 0x00000100 + TxDESC equ 0x00000080 + TxOK equ 0x00000040 + RxORN equ 0x00000020 + RxIDLE equ 0x00000010 + RxEARLY equ 0x00000008 + RxERR equ 0x00000004 + RxDESC equ 0x00000002 + RxOK equ 0x00000001 + +; Interrupt Enable Register Bits + IE equ RxOK + TxOK + +; Revision ID + SIS900B_900_REV equ 0x03 + SIS630A_900_REV equ 0x80 + SIS630E_900_REV equ 0x81 + SIS630S_900_REV equ 0x82 + SIS630EA1_900_REV equ 0x83 + SIS630ET_900_REV equ 0x84 + SIS635A_900_REV equ 0x90 + SIS900_960_REV equ 0x91 + +; Receive Filter Control Register Bits + RFEN equ 0x80000000 + RFAAB equ 0x40000000 + RFAAM equ 0x20000000 + RFAAP equ 0x10000000 + RFPromiscuous equ 0x70000000 + +; Reveive Filter Data Mask + RFDAT equ 0x0000FFFF + +; Eeprom Address + EEPROMSignature equ 0x00 + EEPROMVendorID equ 0x02 + EEPROMDeviceID equ 0x03 + EEPROMMACAddr equ 0x08 + EEPROMChecksum equ 0x0b -SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address * -SIS900_ETH_HLEN equ 14 ;* Size of ethernet header * -SIS900_ETH_ZLEN equ 60 ;* Minimum packet length * -SIS900_DSIZE equ 0x00000fff -SIS900_CRC_SIZE equ 4 -SIS900_RFADDR_shift equ 16 -;SIS900 Symbolic offsets to registers. - SIS900_cr equ 0x0 ; Command Register - SIS900_cfg equ 0x4 ; Configuration Register - SIS900_mear equ 0x8 ; EEPROM Access Register - SIS900_ptscr equ 0xc ; PCI Test Control Register - SIS900_isr equ 0x10 ; Interrupt Status Register - SIS900_imr equ 0x14 ; Interrupt Mask Register - SIS900_ier equ 0x18 ; Interrupt Enable Register - SIS900_epar equ 0x18 ; Enhanced PHY Access Register - SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register - SIS900_txcfg equ 0x24 ; Transmit Configuration Register - SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register - SIS900_rxcfg equ 0x34 ; Receive Configuration Register - SIS900_flctrl equ 0x38 ; Flow Control Register - SIS900_rxlen equ 0x3c ; Receive Packet Length Register - SIS900_rfcr equ 0x48 ; Receive Filter Control Register - SIS900_rfdr equ 0x4C ; Receive Filter Data Register - SIS900_pmctrl equ 0xB0 ; Power Management Control Register - SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register -;SIS900 Command Register Bits - SIS900_RELOAD equ 0x00000400 - SIS900_ACCESSMODE equ 0x00000200 - SIS900_RESET equ 0x00000100 - SIS900_SWI equ 0x00000080 - SIS900_RxRESET equ 0x00000020 - SIS900_TxRESET equ 0x00000010 - SIS900_RxDIS equ 0x00000008 - SIS900_RxENA equ 0x00000004 - SIS900_TxDIS equ 0x00000002 - SIS900_TxENA equ 0x00000001 -;SIS900 Configuration Register Bits - SIS900_DESCRFMT equ 0x00000100 ; 7016 specific - SIS900_REQALG equ 0x00000080 - SIS900_SB equ 0x00000040 - SIS900_POW equ 0x00000020 - SIS900_EXD equ 0x00000010 - SIS900_PESEL equ 0x00000008 - SIS900_LPM equ 0x00000004 - SIS900_BEM equ 0x00000001 - SIS900_RND_CNT equ 0x00000400 - SIS900_FAIR_BACKOFF equ 0x00000200 - SIS900_EDB_MASTER_EN equ 0x00002000 -;SIS900 Eeprom Access Reigster Bits - SIS900_MDC equ 0x00000040 - SIS900_MDDIR equ 0x00000020 - SIS900_MDIO equ 0x00000010 ; 7016 specific - SIS900_EECS equ 0x00000008 - SIS900_EECLK equ 0x00000004 - SIS900_EEDO equ 0x00000002 - SIS900_EEDI equ 0x00000001 -;SIS900 TX Configuration Register Bits - SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding - SIS900_MLB equ 0x20000000 ;Mac Loopback Enable - SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) - SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du -;SIS900 RX Configuration Register Bits - SIS900_AJAB equ 0x08000000 ; - SIS900_ATX equ 0x10000000 ;Accept Transmit Packets - SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes) - SIS900_AEP equ 0x80000000 ;accept error packets -;SIS900 Interrupt Reigster Bits - SIS900_WKEVT equ 0x10000000 - SIS900_TxPAUSEEND equ 0x08000000 - SIS900_TxPAUSE equ 0x04000000 - SIS900_TxRCMP equ 0x02000000 - SIS900_RxRCMP equ 0x01000000 - SIS900_DPERR equ 0x00800000 - SIS900_SSERR equ 0x00400000 - SIS900_RMABT equ 0x00200000 - SIS900_RTABT equ 0x00100000 - SIS900_RxSOVR equ 0x00010000 - SIS900_HIBERR equ 0x00008000 - SIS900_SWINT equ 0x00001000 - SIS900_MIBINT equ 0x00000800 - SIS900_TxURN equ 0x00000400 - SIS900_TxIDLE equ 0x00000200 - SIS900_TxERR equ 0x00000100 - SIS900_TxDESC equ 0x00000080 - SIS900_TxOK equ 0x00000040 - SIS900_RxORN equ 0x00000020 - SIS900_RxIDLE equ 0x00000010 - SIS900_RxEARLY equ 0x00000008 - SIS900_RxERR equ 0x00000004 - SIS900_RxDESC equ 0x00000002 - SIS900_RxOK equ 0x00000001 -;SIS900 Interrupt Enable Reigster Bits - SIS900_IE equ 0x00000001 -;SIS900 Revision ID - SIS900B_900_REV equ 0x03 - SIS630A_900_REV equ 0x80 - SIS630E_900_REV equ 0x81 - SIS630S_900_REV equ 0x82 - SIS630EA1_900_REV equ 0x83 - SIS630ET_900_REV equ 0x84 - SIS635A_900_REV equ 0x90 - SIS900_960_REV equ 0x91 -;SIS900 Receive Filter Control Register Bits - SIS900_RFEN equ 0x80000000 - SIS900_RFAAB equ 0x40000000 - SIS900_RFAAM equ 0x20000000 - SIS900_RFAAP equ 0x10000000 - SIS900_RFPromiscuous equ 0x70000000 -;SIS900 Reveive Filter Data Mask - SIS900_RFDAT equ 0x0000FFFF -;SIS900 Eeprom Address - SIS900_EEPROMSignature equ 0x00 - SIS900_EEPROMVendorID equ 0x02 - SIS900_EEPROMDeviceID equ 0x03 - SIS900_EEPROMMACAddr equ 0x08 - SIS900_EEPROMChecksum equ 0x0b ;The EEPROM commands include the alway-set leading bit. -;SIS900 Eeprom Command - SIS900_EEread equ 0x0180 - SIS900_EEwrite equ 0x0140 - SIS900_EEerase equ 0x01C0 - SIS900_EEwriteEnable equ 0x0130 - SIS900_EEwriteDisable equ 0x0100 - SIS900_EEeraseAll equ 0x0120 - SIS900_EEwriteAll equ 0x0110 - SIS900_EEaddrMask equ 0x013F - SIS900_EEcmdShift equ 16 + EEread equ 0x0180 + EEwrite equ 0x0140 + EEerase equ 0x01C0 + EEwriteEnable equ 0x0130 + EEwriteDisable equ 0x0100 + EEeraseAll equ 0x0120 + EEwriteAll equ 0x0110 + EEaddrMask equ 0x013F + EEcmdShift equ 16 + ;For SiS962 or SiS963, request the eeprom software access - SIS900_EEREQ equ 0x00000400 - SIS900_EEDONE equ 0x00000200 - SIS900_EEGNT equ 0x00000100 + EEREQ equ 0x00000400 + EEDONE equ 0x00000200 + EEGNT equ 0x00000100 -SIS900_pci_revision equ ebx+device.pci_revision -sis900_get_mac_func equ ebx+device.get_MAC -sis900_special_func equ ebx+device.special_func -sis900_table_entries equ ebx+device.table_entries -cur_rx equ ebx+device.cur_rx -sys_msg_board_str equ SysMsgBoardStr -;*************************************************************************** -; Function -; SIS900_probe -; Description -; Searches for an ethernet card, enables it and clears the rx buffer -; If a card was found, it enables the ethernet -> TCPIP link -;not done - still need to probe mii transcievers -;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0 -end if -SIS900_probe: -;******Wake Up Chip******* - stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x40, 0 -;*******Set some PCI Settings********* - call SIS900_adjust_pci_device -;*****Get Card Revision****** - stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x08 - mov [SIS900_pci_revision], al ;save the revision for later use -;****** Look up through the sis900_specific_table - mov esi,sis900_specific_table -.probe_loop: - cmp dword [esi],0 ; Check if we reached end of the list - je .probe_loop_failed - cmp al,[esi] ; Check if revision is OK - je .probe_loop_ok - add esi,12 ; Advance to next entry - jmp .probe_loop -.probe_loop_failed: - jmp SIS900_Probe_Unsupported -;*********Find Get Mac Function********* -.probe_loop_ok: - mov eax,[esi+4] ; Get pointer to "get MAC" function - mov [sis900_get_mac_func],eax - mov eax,[esi+8] ; Get pointer to special initialization fn - mov [sis900_special_func],eax -;******** Get MAC ******** - call dword [sis900_get_mac_func] -;******** Call special initialization fn if requested ******** - cmp dword [sis900_special_func],0 - je .no_special_init - call dword [sis900_special_func] -.no_special_init: -;******** Set table entries ******** - mov al,[SIS900_pci_revision] - cmp al,SIS635A_900_REV - jae .ent16 - cmp al,SIS900B_900_REV - je .ent16 - mov byte [sis900_table_entries],8 - jmp .ent8 -.ent16: - mov byte [sis900_table_entries],16 -.ent8: -;*******Probe for mii transceiver******* -;TODO!!********************* -;*******Initialize Device******* - call sis900_init - ret -SIS900_Probe_Unsupported: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Str_Unsupported - call sys_msg_board_str -end if - or eax, -1 - ret ;*************************************************************************** -; Function: sis900_init ; -; Description: resets the ethernet controller chip and various +; probe +; +; Searches for an ethernet card, enables it and clears the rx buffer +; +; TODO: probe mii transceivers +; +;*************************************************************************** +align 4 +probe: + + stdcall PciWrite8, dword [device.pci_bus], dword [device.pci_dev], 0x40, 0 ; Wake Up Chip + + make_bus_master [device.pci_bus], [device.pci_dev] + +; Get Card Revision + stdcall PciRead8, dword [device.pci_bus], dword [device.pci_dev], 0x08 + mov [pci_revision], al ; save the revision for later use + +; Look up through the specific_table + mov esi, specific_table + .loop: + cmp dword [esi], 0 ; Check if we reached end of the list + je .error + cmp al, [esi] ; Check if revision is OK + je .ok + add esi, 12 ; Advance to next entry + jmp .loop + + .error: + DEBUGF 1, "Device not supported!\n" + or eax, -1 + ret + +; Find Get Mac Function + .ok: + mov eax, [esi+4] ; Get pointer to "get MAC" function + mov [get_mac_func], eax + mov eax, [esi+8] ; Get pointer to special initialization fn + mov [special_func], eax + +; Get MAC + call [get_mac_func] + +; Call special initialization fn if requested + + cmp [special_func],0 + je @f + call [special_func] + @@: + +; Set table entries + + mov byte [table_entries], 16 + cmp [pci_revision], SIS635A_900_REV + jae @f + cmp [pci_revision], SIS900B_900_REV + je @f + mov byte [table_entries], 8 + @@: + +; TODO: Probe for mii transceiver + + +;*************************************************************************** +; +; init +; +; resets the ethernet controller chip and various ; data structures required for sending and receiving packets. ; -; Arguments: -; -; returns: none -;not done ;*************************************************************************** -sis900_init: - call SIS900_reset ;Done - call SIS900_init_rxfilter ;Done - call SIS900_init_txd ;Done - call SIS900_init_rxd ;Done - call SIS900_set_rx_mode ;done - call SIS900_set_tx_mode - ;call SIS900_check_mode +align 4 +init: + + call reset + call init_rxfilter + call init_txd + call init_rxd + call set_rx_mode + call set_tx_mode + ;call check_mode + ; enable interrupts on packet receive + xor eax, eax - inc eax ; eax = 1 = SIS900_RxOK - mov edx, [ebx+device.io_addr] - add edx, SIS900_imr + inc eax ; eax = 1 = RxOK + set_io 0 + set_io imr out dx, eax + ; globally enable interrupts - add edx, SIS900_ier-SIS900_imr + + set_io ier out dx, eax ; eax is still 1 xor eax, eax - ret + + mov [device.mtu], 1514 + + ret ;*************************************************************************** -; Function -; SIS900_reset -; Description -; disables interrupts and soft resets the controller chip ; -;done+ +; reset +; +; disables interrupts and soft resets the controller chip +; ;*************************************************************************** -if defined SIS900_DEBUG - SIS900_Debug_Reset_Failed db 'Reset Failed ',0 -end if -SIS900_reset: - movzx eax, [ebx+device.irq_line] +align 4 +reset: + movzx eax, [device.irq_line] stdcall AttachIntHandler, eax, int_handler, 0 - push ebp - mov ebp, [ebx+device.io_addr] ; base address - ;******Disable Interrupts and reset Receive Filter******* - xor eax, eax ; 0 to initialize - lea edx,[ebp+SIS900_ier] - out dx, eax ; Write 0 to location - lea edx,[ebp+SIS900_imr] - out dx, eax ; Write 0 to location - lea edx,[ebp+SIS900_rfcr] - out dx, eax ; Write 0 to location - ;*******Reset Card*********************************************** - lea edx,[ebp+SIS900_cr] - in eax, dx ; Get current Command Register - or eax, SIS900_RESET ; set flags - or eax, SIS900_RxRESET ; - or eax, SIS900_TxRESET ; - out dx, eax ; Write new Command Register - ;*******Wait Loop************************************************ - push ebx - lea edx,[ebp+SIS900_isr] - mov ecx, 0x03000000 ; Status we would like to see from card - mov ebx, 2001 ; only loop 1000 times -SIS900_Wait: - dec ebx ; 1 less loop - jz SIS900_DoneWait_e ; 1000 times yet? - in eax, dx ; move interrup status to eax - and eax, ecx - xor ecx, eax - jz SIS900_DoneWait - jmp SIS900_Wait -SIS900_DoneWait_e: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Reset_Failed - call sys_msg_board_str -end if -SIS900_DoneWait: - pop ebx - ;*******Set Configuration Register depending on Card Revision******** - lea edx,[ebp+SIS900_cfg] - mov eax, SIS900_PESEL ; Configuration Register Bit - mov cl, [SIS900_pci_revision] ; card revision - cmp cl, SIS635A_900_REV - je SIS900_RevMatch - cmp cl, SIS900B_900_REV ; Check card revision - je SIS900_RevMatch - out dx, eax ; no revision match - jmp SIS900_Reset_Complete -SIS900_RevMatch: ; Revision match - or eax, SIS900_RND_CNT ; Configuration Register Bit - out dx, eax -SIS900_Reset_Complete: - xor eax, eax - pop ebp - ret + +;-------------------------------------------- +; Disable Interrupts and reset Receive Filter + + set_io 0 + set_io ier + xor eax, eax + out dx, eax + + set_io imr + out dx, eax + + set_io rfcr + out dx, eax + +;----------- +; Reset Card + + set_io cr + in eax, dx ; Get current Command Register + or eax, RESET + RxRESET + TxRESET ; set flags + out dx, eax ; Write new Command Register + +;---------- +; Wait loop + + set_io isr + mov ecx, 1000 + .loop: + dec ecx + jz .error + in eax, dx ; move interrup status to eax + cmp eax, 0x03000000 + jne .loop + +;------------------------------------------------------ +; Set Configuration Register depending on Card Revision + + set_io cfg + mov eax, PESEL ; Configuration Register Bit + cmp [pci_revision], SIS635A_900_REV + je .match + cmp [pci_revision], SIS900B_900_REV ; Check card revision + je .match + out dx, eax ; no revision match + jmp .done + + .match: ; Revision match + or eax, RND_CNT ; Configuration Register Bit + out dx, eax + + .done: + xor eax, eax + ret + + .error: + DEBUGF 1, "Reset failed!\n" + or eax, -1 + ret + ;*************************************************************************** -; Function: sis_init_rxfilter ; -; Description: sets receive filter address to our MAC address +; sis_init_rxfilter ; -; Arguments: +; sets receive filter address to our MAC address ; -; returns: -;done+ ;*************************************************************************** -SIS900_init_rxfilter: - push ebp - mov ebp, [ebx+device.io_addr] ; base address - ;****Get Receive Filter Control Register ******** - lea edx,[ebp+SIS900_rfcr] - in eax, dx ; get register - push eax - ;****disable packet filtering before setting filter******* - mov eax, SIS900_RFEN ;move receive filter enable flag - not eax ;1s complement - and eax, [esp] ;disable receiver - out dx, eax ;set receive disabled - ;********load MAC addr to filter data register********* - xor ecx, ecx -SIS900_RXINT_Mac_Write: - ;high word of eax tells card which mac byte to write - mov eax, ecx - lea edx,[ebp+SIS900_rfcr] - shl eax, 16 ; - out dx, eax ; - lea edx,[ebp+SIS900_rfdr] - mov ax, word [ebx+device.mac+ecx*2] ; Get Mac ID word - out dx, ax ; Send Mac ID - inc cl ; send next word - cmp cl, 3 ; more to send? - jne SIS900_RXINT_Mac_Write - ;********enable packet filitering ***** - pop eax ;old register value - lea edx,[ebp+SIS900_rfcr] - or eax, SIS900_RFEN ;enable filtering - out dx, eax ;set register - pop ebp - ret +align 4 +init_rxfilter: + +;------------------------------------ +; Get Receive Filter Control Register + + set_io 0 + set_io rfcr + in eax, dx + push eax + +;----------------------------------------------- +; disable packet filtering before setting filter + + and eax, not RFEN + out dx, eax + +;-------------------------------------- +; load MAC addr to filter data register + + xor ecx, ecx +RXINT_Mac_Write: ; high word of eax tells card which mac byte to write + mov eax, ecx + set_io 0 + set_io rfcr + shl eax, 16 ; + out dx, eax ; + set_io rfdr + mov ax, word [device.mac+ecx*2] ; Get Mac ID word + out dx, ax ; Send Mac ID + inc cl ; send next word + cmp cl, 3 ; more to send? + jne RXINT_Mac_Write + +;------------------------ +; enable packet filtering + + pop eax ;old register value + set_io rfcr + or eax, RFEN ;enable filtering + out dx, eax ;set register + + ret ;*************************************************************************** -;* -;* Function: sis_init_txd -;* -;* Description: initializes the Tx descriptor -;* -;* Arguments: -;* -;* returns: -;*done +; +; init_txd +; +; initializes the Tx descriptor +; ;*************************************************************************** -SIS900_init_txd: - ;********** initialize TX descriptor ************** - mov [ebx+device.txd], dword 0 ;put link to next descriptor in link field - mov [ebx+device.txd+4],dword 0 ;clear status field - lea eax, [ebx+0x1000] - call GetPgAddr - mov [ebx+device.txd+8], eax ;save address to buffer ptr field - ;*************** load Transmit Descriptor Register *************** - mov edx, [ebx+device.io_addr] ; base address - add edx, SIS900_txdp ; TX Descriptor Pointer - add eax, device.txd - 0x1000 ; First Descriptor - out dx, eax ; move the pointer - ret +align 4 +init_txd: + +;------------------------- +; initialize TX descriptor + + mov dword [device.txd], 0 ; put link to next descriptor in link field + mov dword [device.txd+4], 0 ; clear status field + mov dword [device.txd+8], 0 ; ptr to buffer + +;---------------------------------- +; load Transmit Descriptor Register + + set_io 0 + set_io txdp ; TX Descriptor Pointer + lea eax, [device.txd] + GetRealAddr + out dx, eax ; move the pointer + + ret ;*************************************************************************** -;* Function: sis_init_rxd -;* -;* Description: initializes the Rx descriptor ring -;* -;* Arguments: -;* -;* Returns: -;*done +; +; init_rxd +; +; initializes the Rx descriptor ring +; ;*************************************************************************** -SIS900_init_rxd: - xor ecx,ecx - mov [cur_rx], cl ;Set cuurent rx discriptor to 0 - mov eax, ebx - call GetPgAddr - mov esi, eax - ;******** init RX descriptors ******** -SIS900_init_rxd_Loop: - mov edx, ecx ;current descriptor - imul edx, 12 ; - mov eax, ecx ;determine next link descriptor - inc eax ; - cmp eax, NUM_RX_DESC ; - jne SIS900_init_rxd_Loop_0 ; - xor eax, eax ; -SIS900_init_rxd_Loop_0: ; - imul eax, 12 ; - lea eax, [eax+esi+device.rxd] - mov [ebx+device.rxd+edx], eax ;save link to next descriptor - mov [ebx+device.rxd+edx+4],dword RX_BUFF_SZ ;status bits init to buf size - mov eax, ecx ;find where the buf is located - imul eax,RX_BUFF_SZ ; - lea eax, [eax+esi+0x1000+NUM_TX_DESC*TX_BUFF_SZ] - mov [ebx+device.rxd+edx+8], eax ;save buffer pointer - inc ecx ;next descriptor - cmp ecx, NUM_RX_DESC ; - jne SIS900_init_rxd_Loop ; - ;********* load Receive Descriptor Register with address of first - ; descriptor********* - mov edx, [ebx+device.io_addr] - add edx, SIS900_rxdp - lea eax, [esi+device.rxd] - out dx, eax - ret +align 4 +init_rxd: + +; init RX descriptors + mov ecx, NUM_RX_DESC + lea esi, [device.rxd] + + .loop: + lea eax, [esi + 16] + GetRealAddr + mov dword [esi+0], eax + mov dword [esi+4], RX_BUFF_SZ + + stdcall KernelAlloc, RX_BUFF_SZ + test eax, eax + jz .fail + mov dword [esi+12], eax + GetRealAddr + mov dword [esi+8], eax + add esi, 16 + loop .loop + + lea eax, [device.rxd] + GetRealAddr + mov dword [esi - 16], eax ; correct last descriptor link ptr + +; And output ptr to first desc, to device + + set_io 0 + set_io rxdp + out dx, eax + + mov [device.cur_rx], 0 ; Set curent rx discriptor to 0 + + .fail: ;;; TODO: abort instead! + ret + ;*************************************************************************** -;* Function: sis900_set_tx_mode -;* -;* Description: -;* sets the transmit mode to allow for full duplex -;* -;* -;* Arguments: -;* -;* Returns: -;* -;* Comments: -;* If you are having problems transmitting packet try changing the -;* Max DMA Burst, Possible settings are as follows: -;* 0x00000000 = 512 bytes -;* 0x00100000 = 4 bytes -;* 0x00200000 = 8 bytes -;* 0x00300000 = 16 bytes -;* 0x00400000 = 32 bytes -;* 0x00500000 = 64 bytes -;* 0x00600000 = 128 bytes -;* 0x00700000 = 256 bytes +; +; set_tx_mode +; +; sets the transmit mode to allow for full duplex +; +; If you are having problems transmitting packet try changing the +; Max DMA Burst, Possible settings are as follows: +; +; 0x00000000 = 512 bytes +; 0x00100000 = 4 bytes +; 0x00200000 = 8 bytes +; 0x00300000 = 16 bytes +; 0x00400000 = 32 bytes +; 0x00500000 = 64 bytes +; 0x00600000 = 128 bytes +; 0x00700000 = 256 bytes +; ;*************************************************************************** -SIS900_set_tx_mode: - push ebp - mov ebp,[ebx+device.io_addr] - lea edx,[ebp+SIS900_cr] - in eax, dx ; Get current Command Register - or eax, SIS900_TxENA ;Enable Receive - out dx, eax - lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset - mov eax, SIS900_ATP ;allow automatic padding - or eax, SIS900_HBI ;allow heartbeat ignore - or eax, SIS900_CSI ;allow carrier sense ignore - or eax, 0x00600000 ;Max DMA Burst - or eax, 0x00000100 ;TX Fill Threshold - or eax, 0x00000020 ;TX Drain Threshold - out dx, eax - pop ebp - ret +align 4 +set_tx_mode: + + set_io 0 + set_io cr + in eax, dx ; Get current Command Register + or eax, TxENA ; Enable Receive + out dx, eax + + set_io txcfg ; Transmit config Register offset + mov eax, ATP + HBI + CSI +0x00600120 + ; allow automatic padding + ; allow heartbeat ignore + ; allow carrier sense ignore + ; Max DMA Burst (128 bytes) + ; TX Fill Threshold + ; TX Drain Threshold + out dx, eax + + ret ;*************************************************************************** -;* Function: sis900_set_rx_mode -;* -;* Description: -;* sets the receive mode to accept all broadcast packets and packets -;* with our MAC address, and reject all multicast packets. Also allows -;* full-duplex -;* -;* Arguments: -;* -;* Returns: -;* -;* Comments: -;* If you are having problems receiving packet try changing the -;* Max DMA Burst, Possible settings are as follows: -;* 0x00000000 = 512 bytes -;* 0x00100000 = 4 bytes -;* 0x00200000 = 8 bytes -;* 0x00300000 = 16 bytes -;* 0x00400000 = 32 bytes -;* 0x00500000 = 64 bytes -;* 0x00600000 = 128 bytes -;* 0x00700000 = 256 bytes +; +; set_rx_mode +; +; sets the receive mode to accept all broadcast packets and packets +; with our MAC address, and reject all multicast packets. Also allows +; full-duplex +; +; If you are having problems receiving packet try changing the +; Max DMA Burst, Possible settings are as follows: +; +; 0x00000000 = 512 bytes +; 0x00100000 = 4 bytes +; 0x00200000 = 8 bytes +; 0x00300000 = 16 bytes +; 0x00400000 = 32 bytes +; 0x00500000 = 64 bytes +; 0x00600000 = 128 bytes +; 0x00700000 = 256 bytes +; ;*************************************************************************** -SIS900_set_rx_mode: - push ebp - mov ebp,[ebx+device.io_addr] - ;**************update Multicast Hash Table in Receive Filter - xor cl, cl -SIS900_set_rx_mode_Loop: - mov eax, ecx - shl eax, 1 - lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset - mov eax, 4 ;determine table entry - add al, cl - shl eax, 16 - out dx, eax ;tell card which entry to modify - lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset - mov eax, 0xffff ;entry value - out dx, ax ;write value to table in card - inc cl ;next entry - cmp cl,[sis900_table_entries] ; - jl SIS900_set_rx_mode_Loop - ;*******Set Receive Filter Control Register************* - lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset - mov eax, SIS900_RFAAB ;accecpt all broadcast packets - or eax, SIS900_RFAAM ;accept all multicast packets - or eax, SIS900_RFAAP ;Accept all packets - or eax, SIS900_RFEN ;enable receiver filter - out dx, eax - ;******Enable Receiver************ - lea edx,[ebp+SIS900_cr] ; Command Register offset - in eax, dx ; Get current Command Register - or eax, SIS900_RxENA ;Enable Receive - out dx, eax - ;*********Set - lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset - mov eax, SIS900_ATX ;Accept Transmit Packets - ; (Req for full-duplex and PMD Loopback) - or eax, 0x00600000 ;Max DMA Burst - or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes - out dx, eax ; - pop ebp - ret +align 4 +set_rx_mode: + +;---------------------------------------------- +; update Multicast Hash Table in Receive Filter + + xor cl, cl + .loop: + set_io 0 + set_io rfcr ; Receive Filter Control Reg offset + mov eax, 4 ; determine table entry + add al, cl + shl eax, 16 + out dx, eax ; tell card which entry to modify + + set_io rfdr ; Receive Filter Control Reg offset + mov eax, 0xffff ; entry value + out dx, ax ; write value to table in card + + inc cl ; next entry + cmp cl, [table_entries] + jl .loop + +;------------------------------------ +; Set Receive Filter Control Register + + set_io rfcr ; Receive Filter Control Register offset + mov eax, RFAAB + RFAAM + RFAAP + RFEN + ; accecpt all broadcast packets + ; accept all multicast packets + ; Accept all packets + ; enable receiver filter + out dx, eax +;---------------- +; Enable Receiver + + set_io cr + in eax, dx ; Get current Command Register + or eax, RxENA ; Enable Receive + out dx, eax + +;------------------- +; Configure Receiver + + set_io rxcfg ; Receive Config Register offset + mov eax, ATX + 0x00600002 + ; Accept Transmit Packets + ; (Req for full-duplex and PMD Loopback) + ; Max DMA Burst + ; RX Drain Threshold, 8X8 bytes or 64bytes + out dx, eax + + ret ;*************************************************************************** -; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model -; * @pci_dev: the sis900 pci device -; * @net_dev: the net device to get address for -; * -; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM -; * is shared by -; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first -; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access -; * by LAN, otherwise is not. After MAC address is read from EEPROM, send -; * EEDONE signal to refuse EEPROM access by LAN. -; * The EEPROM map of SiS962 or SiS963 is different to SiS900. -; * The signature field in SiS962 or SiS963 spec is meaningless. -; * MAC address is read into @net_dev->dev_addr. -; *done -;* -;* Return 0 is EAX = failure -;*Done+ +; +; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model +; +; SiS962 or SiS963 model, use EEPROM to store MAC address. +; EEPROM is shared by LAN and 1394. +; When access EEPROM, send EEREQ signal to hardware first, and wait for EEGNT. +; If EEGNT is ON, EEPROM is permitted to be accessed by LAN, otherwise is not. +; After MAC address is read from EEPROM, send +; EEDONE signal to refuse EEPROM access by LAN. +; The EEPROM map of SiS962 or SiS963 is different to SiS900. +; The signature field in SiS962 or SiS963 spec is meaningless. +; +; Return 0 is EAX = failure +; ;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0 -SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0 -SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0 -SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0 -end if +align 4 SIS960_get_mac_addr: - push ebp - mov ebp,[ebx+device.io_addr] - ;**********Send Request for eeprom access********************* - lea edx,[ebp+SIS900_mear] ; Eeprom access register - mov eax, SIS900_EEREQ ; Request access to eeprom - out dx, eax ; Send request - xor ecx,ecx ; - ;******Loop 4000 times and if access not granted error out***** -SIS96X_Get_Mac_Wait: - in eax, dx ;get eeprom status - and eax, SIS900_EEGNT ;see if eeprom access granted flag is set - jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom - inc ecx ;else keep waiting - cmp ecx, 4000 ;have we tried 4000 times yet? - jl SIS96X_Get_Mac_Wait ;if not ask again - xor eax, eax ;return zero in eax indicating failure - ;*******Debug ********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Failed - call sys_msg_board_str -end if - jmp SIS960_get_mac_addr_done - ;**********EEprom access granted, read MAC from card************* -SIS900_Got_EEP_Access: + +;------------------------------- +; Send Request for eeprom access + + set_io 0 + set_io mear ; Eeprom access register + mov eax, EEREQ ; Request access to eeprom + out dx, eax ; Send request + +;----------------------------------------------------- +; Loop 4000 times and if access not granted, error out + + mov ecx, 4000 + .loop: + in eax, dx ; get eeprom status + test eax, EEGNT ; see if eeprom access granted flag is set + jnz .got_access ; if it is, go access the eeprom + loop .loop ; else keep waiting + + DEBUGF 1, "Access to EEprom failed!\n", 0 + + set_io mear ; Eeprom access register + mov eax, EEDONE ; tell eeprom we are done + out dx, eax + + or eax, -1 ; error + ret + + .got_access: + +;------------------------------------------ +; EEprom access granted, read MAC from card + ; zero based so 3-16 bit reads will take place - mov ecx, 2 -SIS96x_mac_read_loop: - mov eax, SIS900_EEPROMMACAddr ;Base Mac Address - add eax, ecx ;Current Mac Byte Offset - push ecx - call sis900_read_eeprom ;try to read 16 bits - pop ecx - mov word [ebx+device.mac+ecx*2], ax ;save 16 bits to the MAC ID varible - dec ecx ;one less word to read - jns SIS96x_mac_read_loop ;if more read more - mov eax, 1 ;return non-zero indicating success - ;*******Debug Print MAC ID to debug window********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Address2 - call sys_msg_board_str - lea edx, [ebx+device.mac] - call Create_Mac_String -end if - ;**********Tell EEPROM We are Done Accessing It********************* -SIS960_get_mac_addr_done: - lea edx,[ebp+SIS900_mear] ; Eeprom access register - mov eax, SIS900_EEDONE ;tell eeprom we are done - out dx,eax - pop ebp - ret -;*************************************************************************** -;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model -;* @pci_dev: the sis900 pci device -;* @net_dev: the net device to get address for -;* -;* Older SiS900 and friends, use EEPROM to store MAC address. -;* MAC address is read from read_eeprom() into @net_dev->dev_addr. -;* done/untested -;*************************************************************************** -SIS900_get_mac_addr: - ;*******Debug ********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Start - call sys_msg_board_str -end if - ;******** check to see if we have sane EEPROM ******* - mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature - call sis900_read_eeprom ;try to read 16 bits - cmp ax, 0xffff - je SIS900_Bad_Eeprom - cmp ax, 0 - je SIS900_Bad_Eeprom - ;**************Read MacID************** - ; zero based so 3-16 bit reads will take place - mov ecx, 2 -SIS900_mac_read_loop: - mov eax, SIS900_EEPROMMACAddr ;Base Mac Address - add eax, ecx ;Current Mac Byte Offset - push ecx - call sis900_read_eeprom ;try to read 16 bits - pop ecx - mov word [ebx+device.mac+ecx*2], ax ;save 16 bits to the MAC ID storage - dec ecx ;one less word to read - jns SIS900_mac_read_loop ;if more read more - mov eax, 1 ;return non-zero indicating success - ;*******Debug Print MAC ID to debug window********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Address - call sys_msg_board_str - lea edx, [ebx+device.mac] - call Create_Mac_String -end if - ret -SIS900_Bad_Eeprom: - xor eax, eax - ;*******Debug ********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Failed - call sys_msg_board_str -end if - ret + mov ecx, 2 + .read_loop: + mov eax, EEPROMMACAddr ; Base Mac Address + add eax, ecx ; Current Mac Byte Offset + push ecx + call read_eeprom ; try to read 16 bits + pop ecx + mov word [device.mac+ecx*2], ax ; save 16 bits to the MAC ID varible + dec ecx ; one less word to read + jns .read_loop ; if more read more + mov eax, 1 ; return non-zero indicating success + + DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 + +;------------------------------------- +; Tell EEPROM We are Done Accessing It + + .done: + set_io 0 + set_io mear ; Eeprom access register + mov eax, EEDONE ; tell eeprom we are done + out dx, eax + + xor eax, eax ; ok + ret + + + + ;*************************************************************************** -;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635 -;* -;* +; +; get_mac_addr: - Get MAC address for stand alone SiS900 model +; +; Older SiS900 and friends, use EEPROM to store MAC address. +; ;*************************************************************************** +align 4 +get_mac_addr: + +;------------------------------------ +; check to see if we have sane EEPROM + + mov eax, EEPROMSignature ; Base Eeprom Signature + call read_eeprom ; try to read 16 bits + cmp ax, 0xffff + je .err + test ax, ax + je .err + +;----------- +; Read MacID + +; zero based so 3-16 bit reads will take place + + mov ecx, 2 + .loop: + mov eax, EEPROMMACAddr ;Base Mac Address + add eax, ecx ;Current Mac Byte Offset + push ecx + call read_eeprom ;try to read 16 bits + pop ecx + mov word [device.mac+ecx*2], ax ;save 16 bits to the MAC ID storage + dec ecx ;one less word to read + jns mac_read_loop ;if more read more + + DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 + + xor eax, eax + ret + + + .err: + DEBUGF 1, "Access to EEprom failed!\n", 0 + + or eax, -1 + ret + + +;*************************************************************************** +; +; Get_Mac_SIS635_900_REV: - Get MAC address for model 635 +; +;*************************************************************************** +align 4 Get_Mac_SIS635_900_REV: -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Start - call sys_msg_board_str -end if - push ebp - mov ebp,[ebx+device.io_addr] - lea edx,[ebp+SIS900_rfcr] - in eax,dx - mov edi,eax ; EDI=rfcrSave - lea edx,[ebp+SIS900_cr] - or eax,SIS900_RELOAD - out dx,eax - xor eax,eax - out dx,eax - ; Disable packet filtering before setting filter - lea edx,[ebp+SIS900_rfcr] - mov eax,edi - and edi,not SIS900_RFEN - out dx,eax - ; Load MAC to filter data register - xor ecx,ecx - lea esi,[ebx+device.mac] -.get_mac_loop: - lea edx,[ebp+SIS900_rfcr] - mov eax,ecx - shl eax,SIS900_RFADDR_shift - out dx,eax - lea edx,[ebp+SIS900_rfdr] - in eax,dx - mov [esi],ax - add esi,2 - inc ecx - cmp ecx,3 - jne .get_mac_loop - ; Enable packet filtering - ;lea edx,[ebp+SIS900_rfcr] - ;mov eax,edi - ;or eax,SIS900_RFEN - ;out dx, eax - ;*******Debug Print MAC ID to debug window********************** -if defined SIS900_DEBUG - mov esi,SIS900_Debug_Str_GetMac_Address - call sys_msg_board_str - lea edx, [ebx+device.mac] - call Create_Mac_String -end if - pop ebp - ret -;*************************************************************************** -;* Function: sis900_read_eeprom -;* -;* Description: reads and returns a given location from EEPROM -;* -;* Arguments: eax - location: requested EEPROM location -;* -;* Returns: eax : contents of requested EEPROM location -;* -; Read Serial EEPROM through EEPROM Access Register, Note that location is -; in word (16 bits) unit */ -;done+ -;*************************************************************************** -sis900_read_eeprom: - push esi - push edx - push ecx - push ebx - push ebp - mov ebp,[ebx+device.io_addr] - mov ebx, eax ;location of Mac byte to read - or ebx, SIS900_EEread ; - lea edx,[ebp+SIS900_mear] ; Eeprom access register - xor eax, eax ; start send - out dx,eax - call SIS900_Eeprom_Delay_1 - mov eax, SIS900_EECLK - out dx, eax - call SIS900_Eeprom_Delay_1 - ;************ Shift the read command (9) bits out. ********* - mov cl, 8 ; -sis900_read_eeprom_Send: - mov eax, 1 - shl eax, cl - and eax, ebx - jz SIS900_Read_Eeprom_8 - mov eax, 9 - jmp SIS900_Read_Eeprom_9 -SIS900_Read_Eeprom_8: - mov eax, 8 -SIS900_Read_Eeprom_9: - out dx, eax - call SIS900_Eeprom_Delay_1 - or eax, SIS900_EECLK - out dx, eax - call SIS900_Eeprom_Delay_1 - cmp cl, 0 - je sis900_read_eeprom_Send_Done - dec cl - jmp sis900_read_eeprom_Send - ;********************* -sis900_read_eeprom_Send_Done: - mov eax, SIS900_EECS ; - out dx, eax - call SIS900_Eeprom_Delay_1 - ;********** Read 16-bits of data in *************** - mov cx, 16 ;16 bits to read -sis900_read_eeprom_Send2: - mov eax, SIS900_EECS - out dx, eax - call SIS900_Eeprom_Delay_1 - or eax, SIS900_EECLK - out dx, eax - call SIS900_Eeprom_Delay_1 - in eax, dx - shl ebx, 1 - and eax, SIS900_EEDO - jz SIS900_Read_Eeprom_0 - or ebx, 1 -SIS900_Read_Eeprom_0: - dec cx - jnz sis900_read_eeprom_Send2 - ;************** Terminate the EEPROM access. ************** - xor eax, eax - out dx, eax - call SIS900_Eeprom_Delay_1 - mov eax, SIS900_EECLK - out dx, eax - mov eax, ebx - and eax, 0x0000ffff ;return only 16 bits - pop ebp - pop ebx - pop ecx - pop edx - pop esi - ret -;*************************************************************************** -; Function -; SIS900_Eeprom_Delay_1 -; Description -; -; -; -; -;*************************************************************************** -SIS900_Eeprom_Delay_1: - push eax - in eax, dx - pop eax - ret + set_io 0 + set_io rfcr + in eax, dx + mov edi, eax ; EDI=rfcrSave + + set_io cr + or eax, RELOAD + out dx, eax + + xor eax, eax + out dx, eax + +;----------------------------------------------- +; Disable packet filtering before setting filter + + set_io rfcr + mov eax, edi + and edi, not RFEN + out dx, eax + +;--------------------------------- +; Load MAC to filter data register + + mov ecx, 3 + lea edi, [device.mac] + .loop: + set_io 0 + set_io rfcr + mov eax, ecx + shl eax, RFADDR_shift + out dx, eax + + set_io rfdr + in eax, dx + stosw + loop .loop + +;------------------------ +; Enable packet filtering + +; set_io rfcr +; mov eax, edi +; or eax, RFEN +; out dx, eax + + xor eax, eax + ret + +;*************************************************************************** +; +; read_eeprom +; +; reads and returns a given location from EEPROM +; +; IN: si = addr +; OUT: ax = data +; +;*************************************************************************** +align 4 +read_eeprom: + + set_io 0 + set_io mear + + xor eax, eax ; start send + out dx, eax + ee_delay + + or eax, EECLK + out dx, eax + ee_delay + +;------------------------------------ +; Send the read command + + or esi, EEread + mov ecx, 1 shl 9 + + .loop: + mov eax, EECS + test esi, ecx + jz @f + or eax, EEDI + @@: + out dx, eax + ee_delay + + or eax, EECLK + out dx, eax + ee_delay + + shr esi, 1 + jnc .loop + + mov eax, EECS + out dx, eax + ee_delay + +;------------------------ +; Read 16-bits of data in + + xor esi, esi + mov cx, 16 + .loop2: + mov eax, EECS + out dx, eax + ee_delay + + or eax, EECLK + out dx, eax + ee_delay + + in eax, dx + shl esi, 1 + test eax, EEDO + jz @f + inc esi + @@: + loop .loop2 + +;---------------------------- +; Terminate the EEPROM access + + xor eax, eax + out dx, eax + ee_delay + + mov eax, EECLK + out dx, eax + ee_delay + + movzx eax, si + + ret + + + +align 4 write_mac: DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n' add esp, 6 ret ;*************************************************************************** -; Function -; int_handler -; Description -; handles received IRQs, which signal received packets ; -; Currently only supports one descriptor per packet, if packet is fragmented -; between multiple descriptors you will lose part of the packet +; int_handler +; +; handles received IRQs, which signal received packets +; +; Currently only supports one descriptor per packet, if packet is fragmented +; between multiple descriptors you will lose part of the packet +; ;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0 -SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0 -SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0 -end if +align 4 int_handler: ; find pointer of device which made IRQ occur - mov esi, DEV_LIST - mov ecx, [NUM_DEV] + mov esi, device_list + mov ecx, [devices] test ecx, ecx jz .nothing .nextdevice: mov ebx, [esi] - mov edx, [ebx+device.io_addr] - add edx, SIS900_isr + set_io 0 + set_io isr in eax, dx ; note that this clears all interrupts - test al, SIS900_RxOK + test ax, IE jnz .got_it loop .nextdevice .nothing: ret .got_it: - ;**************Get Status ************** - movzx eax, [ebx+device.cur_rx] ;find current discriptor - imul eax, 12 ; - mov ecx, [ebx+device.rxd+eax+4] ; get receive status - ;**************Check Status ************** - ;Check RX_Status to see if packet is waiting - test ecx, 0x80000000 - jnz SIS900_poll_IS_packet - ret - ;**********There is a packet waiting check it for errors************** -SIS900_poll_IS_packet: - test ecx, 0x67C0000 ;see if there are any errors - jnz SIS900_Poll_Error_Status - ;**************Check size of packet************* - and ecx, SIS900_DSIZE ;get packet size minus CRC - cmp ecx, SIS900_CRC_SIZE - ;make sure packet contains data - jle SIS900_Poll_Error_Size - ;*******Copy Good Packet to receive buffer****** - sub ecx, SIS900_CRC_SIZE ;dont want crc - ; update statistics - inc dword [ebx+device.packets_rx] - add dword [ebx+device.bytes_rx], ecx - adc dword [ebx+device.bytes_rx+4], 0 - push ecx - stdcall KernelAlloc, ecx - pop ecx - test eax, eax - jz int_handler.nothing - push ebx - push .return ; return address for EthReceiver - ;**********Continue copying packet**************** - push ecx eax ; save buffer pointer and size for EthReceiver - mov edi, eax - movzx esi, byte [ebx+device.cur_rx] - imul esi, RX_BUFF_SZ - lea esi, [esi+ebx+0x1000+NUM_TX_DESC*TX_BUFF_SZ] - ; first copy dword-wise, divide size by 4 - shr ecx, 2 - rep movsd ; copy the dwords - mov ecx, [esp+4] - and ecx, 3 ; - rep movsb - ;********Debug, tell user we have a good packet************* -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Pull_Packet_good - call sys_msg_board_str -end if - jmp EthReceiver -.return: - pop ebx - jmp SIS900_Poll_Cnt - ;*************Error occured let user know through debug window*********** -SIS900_Poll_Error_Status: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Pull_Bad_Packet_Status - call sys_msg_board_str -end if - jmp SIS900_Poll_Cnt -SIS900_Poll_Error_Size: -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Pull_Bad_Packet_Size - call sys_msg_board_str -end if - ;*************Increment to next available descriptor************** -SIS900_Poll_Cnt: - ;Reset status, allow ethernet card access to descriptor - movzx eax, [ebx+device.cur_rx] - lea eax, [eax*3] - mov ecx, RX_BUFF_SZ - mov [ebx+device.rxd+eax*4+4], ecx ; - inc [ebx+device.cur_rx] ;get next descriptor - and [ebx+device.cur_rx],NUM_RX_DESC-1 ;only 4 descriptors 0-3 - ;******Enable Receiver************ - mov edx, [ebx+device.io_addr] - add edx, SIS900_cr ; Command Register offset - in eax, dx ; Get current Command Register - or eax, SIS900_RxENA ;Enable Receive - out dx, eax - ret + + test ax, RxOK + jz .no_rx + + push ax + +;----------- +; Get Status + movzx eax, [device.cur_rx] ; find current discriptor + shl eax, 4 ; * 16 + mov ecx, dword[device.rxd+eax+4] ; get receive status + +;------------------------------------------- +; Check RX_Status to see if packet is waiting + test ecx, 0x80000000 + jnz .is_packet + ret + +;---------------------------------------------- +; There is a packet waiting check it for errors + .is_packet: + test ecx, 0x67C0000 ; see if there are any errors + jnz .error_status + +;--------------------- +; Check size of packet + and ecx, DSIZE ; get packet size minus CRC + sub ecx, CRC_SIZE ; make sure packet contains data + jle .error_size + +; update statistics + inc dword [device.packets_rx] + add dword [device.bytes_rx], ecx + adc dword [device.bytes_rx+4], 0 + + push ebx + push .return + push ecx ; packet size + push [device.rxd+eax+12] ; packet ptr + DEBUGF 1, "Packet received OK\n" + jmp EthReceiver + .return: + pop ebx + +; Reset status, allow ethernet card access to descriptor + movzx ecx, [device.cur_rx] + shl ecx, 4 ; *16 + mov ecx, [device.rxd+ecx] + stdcall KernelAlloc, RX_BUFF_SZ + test eax, eax + jz .fail + mov dword [ecx+12], eax + GetRealAddr + mov dword [ecx+8], eax + mov dword [ecx+4], RX_BUFF_SZ + + inc [device.cur_rx] ; get next descriptor + and [device.cur_rx], NUM_RX_DESC-1 ; only 4 descriptors 0-3 + +; Enable Receiver + set_io 0 + set_io cr ; Command Register offset + in eax, dx ; Get current Command Register + or eax, RxENA ; Enable Receiver + out dx, eax + + pop ax + jmp .no_rx + + .error_status: + + DEBUGF 1, "Packet error: %x\n", ecx + jmp .continue + + .error_size: + + DEBUGF 1, "Packet too large/small\n" + jmp .continue + + .no_rx: + test ax, TxOk + jz .no_tx + + ;;; TODO: free all unused buffers + stdcall KernelFree, eax + + .no_tx: + + ret + + + ;*************************************************************************** ; Function ; transmit @@ -1231,167 +1245,46 @@ SIS900_Poll_Cnt: ; only one transmit descriptor is used ; ;*************************************************************************** -if defined SIS900_DEBUG -SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0 -SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0 -end if -str1 db 'Transmitting packet:',13,10,0 -str2 db ' ',0 +align 4 transmit: - cmp dword [esp+8], MAX_ETH_FRAME_SIZE - jg transmit_finish - cmp dword [esp+8], 60 - jl transmit_finish - push ebp - mov ebp, [ebx+device.io_addr] ; Base Address - ;******** Stop the transmitter ******** - lea edx,[ebp+SIS900_cr] ; Command Register offset - in eax, dx ; Get current Command Register - or eax, SIS900_TxDIS ; Disable Transmitter - out dx, eax - ;*******load Transmit Descriptor Register ******* - lea edx,[ebp+SIS900_txdp] - mov eax, ebx - call GetPgAddr - add eax, device.txd - out dx, eax - ;******* copy packet to descriptor******* - mov esi, [esp+8] - lea edi, [ebx+0x1000] - mov ecx, [esp+12] - mov edx, ecx - shr ecx, 2 - and edx, 3 - rep movsd - mov ecx, edx - rep movsb - ;**************set length tag************** - mov ecx, [esp+12] ;restore packet size - and ecx, SIS900_DSIZE ; - inc [ebx+device.packets_tx] - add dword [ebx+device.bytes_tx], ecx - adc dword [ebx+device.bytes_tx+4], 0 - ;**************pad to minimum packet size **************not needed - ;cmp ecx, SIS900_ETH_ZLEN - ;jge SIS900_transmit_Size_Ok - ;push ecx - ;mov ebx, SIS900_ETH_ZLEN - ;sub ebx, ecx - ;mov ecx, ebx - ;rep movsb - ;pop ecx -SIS900_transmit_Size_Ok: - or ecx, 0x80000000 ;card owns descriptor - mov [ebx+device.txd+4], ecx -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Transmit_Packet - call sys_msg_board_str -end if - ;***************restart the transmitter ******** - lea edx,[ebp+SIS900_cr] - in eax, dx ; Get current Command Register - or eax, SIS900_TxENA ; Enable Transmitter - out dx, eax - ;****make sure packet transmitted successfully**** -; mov esi,10 -; call delay_ms - mov eax, [ebx+device.txd+4] - and eax, 0x6200000 - jz SIS900_transmit_OK - ;**************Tell user there was an error through debug window -if defined SIS900_DEBUG - mov esi, SIS900_Debug_Transmit_Packet_Err - call sys_msg_board_str -end if -SIS900_transmit_OK: - pop ebp -transmit_finish: - ret -;*************************************************************************** -;* Function: Create_Mac_String -;* -;* Description: Converts the 48 bit value to a string for display -;* -;* String Format: XX:XX:XX:XX:XX:XX -;* -;* Arguments: node_addr is location of 48 bit MAC ID -;* -;* Returns: Prints string to general debug window -;* -;* -;done -;*************************************************************************** -if defined SIS900_DEBUG + cmp dword [esp+8], MAX_ETH_FRAME_SIZE + jg transmit_finish + + cmp dword [esp+8], 60 + jl transmit_finish + + movzx ecx, [device.cur_tx] + mov ecx, [device.txd+ecx*16] + +;; TODO: check if desc is empty (for example: check for eax, 0x6200000 at [ecx+4] +;;; or: count number of available descriptors + + mov eax, [esp+4] + mov dword [ecx + 12], eax + GetRealAddr + mov dword [ecx + 8], eax + + mov eax, [esp+8] + and eax, DSIZE + or eax, 0x80000000 ; card owns descriptor + mov dword [ecx + 4], eax + +; update stats + inc [device.packets_tx] + add dword [device.bytes_tx], ecx + adc dword [device.bytes_tx+4], 0 + + ret -SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9' - db 'A','B','C','D','E','F' -Mac_str_build: times 20 db 0 -Create_Mac_String: - pusha - xor ecx, ecx -Create_Mac_String_loop: - mov al,byte [edx+ecx];[node_addr+ecx] - push eax - shr eax, 4 - and eax, 0x0f - mov bl, byte [SIS900_Char_String+eax] - mov [Mac_str_build+ecx*3], bl - pop eax - and eax, 0x0f - mov bl, byte [SIS900_Char_String+eax] - mov [Mac_str_build+1+ecx*3], bl - cmp ecx, 5 - je Create_Mac_String_done - mov bl, ':' - mov [Mac_str_build+2+ecx*3], bl - inc ecx - jmp Create_Mac_String_loop -Create_Mac_String_done: ;Insert CR and Zero Terminate - mov [Mac_str_build+2+ecx*3],byte 13 - mov [Mac_str_build+3+ecx*3],byte 10 - mov [Mac_str_build+4+ecx*3],byte 0 - mov esi, Mac_str_build - call sys_msg_board_str ;Print String to message board - popa - ret -end if -;*************************************************************************** -;* Set device to be a busmaster in case BIOS neglected to do so. -;* Also adjust PCI latency timer to a reasonable value, 64. -;*************************************************************************** -SIS900_adjust_pci_device: - ;*******Get current setting************************ - stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04 - ;******see if its already set as bus master******** - mov cx, ax - and cx,5 - cmp cx,5 - je SIS900_adjust_pci_device_Latency - ;******Make card a bus master******* - mov cx, ax ;value to write - or cx,5 - stdcall PciWrite16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04, ecx - ;******Check latency setting*********** -SIS900_adjust_pci_device_Latency: - ;*******Get current latency setting************************ - stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D - ;******see if its aat least 64 clocks******** - cmp al,64 - jge SIS900_adjust_pci_device_Done - ;******Set latency to 32 clocks******* - stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D, 64 - ;******Check latency setting*********** -SIS900_adjust_pci_device_Done: - ret ; End of code align 4 ; Place all initialised data here -NUM_DEV dd 0 +devices dd 0 -sis900_specific_table: +specific_table: ; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0 ; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0 dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0 @@ -1399,15 +1292,15 @@ sis900_specific_table: dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0 dd SIS900_960_REV,SIS960_get_mac_addr,0 - dd SIS900B_900_REV,SIS900_get_mac_addr,0 - dd 0,0,0,0 ; end of list + dd SIS900B_900_REV,get_mac_addr,0 + dd 0 ; end of list -version dd (5 shl 16) or (API_VERSION and 0xFFFF) -my_service db 'SIS900',0 ; max 16 chars include zero +version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) +my_service db 'SIS900',0 ; max 16 chars include zero -include_debug_strings ; All data wich FDO uses will be included here +include_debug_strings ; All data wich FDO uses will be included here -section '.data' data readable writable align 16 ; place all uninitialized data place here +section '.data' data readable writable align 16; place all uninitialized data place here -DEV_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 diff --git a/kernel/branches/net/network/ARP.inc b/kernel/branches/net/network/ARP.inc index 1c16170011..e7d6a204dc 100644 --- a/kernel/branches/net/network/ARP.inc +++ b/kernel/branches/net/network/ARP.inc @@ -112,7 +112,7 @@ ARP_init: ; ; This function resets all ARP variables ; -; IN: eax = IPv4 address +; IN: eax = IPv4 address ; OUT: eax = -1 on error, else eax = first two bytes of mac ; ( high 16 bits are zero) ; ebx = last four bytes of mac ; TODO: special eax value for 'request send' @@ -130,18 +130,18 @@ ARP_IP_to_MAC: ; else ; destination is remote, so pass to gateway - xor edx, edx ; TODO: find device num in edx + xor edx, edx ;;; TODO: find device num in edx - mov ebx, [IP_LIST+edx] - and ebx, [SUBNET_LIST+edx] + mov ebx, [IP_LIST + edx] + and ebx, [SUBNET_LIST + edx] mov ecx, eax - and ecx, [SUBNET_LIST+edx] + and ecx, [SUBNET_LIST + edx] cmp ecx, ebx je .local - mov eax, [GATEWAY_LIST+edx] + mov eax, [GATEWAY_LIST + edx] DEBUGF 1,"requested IP is not on subnet, using gateway\n" .local: @@ -274,7 +274,8 @@ ARP_create_request: DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx push edx ecx - jmp NET_send + call [ebx + NET_DEVICE.transmit] + ret .exit: add esp, 8 @@ -572,7 +573,8 @@ ARP_handler: DEBUGF 1,"ARP_Handler - Sending reply \n" - jmp NET_send ; And send it! + call [ebx + NET_DEVICE.transmit] + ret .exit: call kernel_free diff --git a/kernel/branches/net/network/IPv4.inc b/kernel/branches/net/network/IPv4.inc index e9c5fbf037..59e288046e 100644 --- a/kernel/branches/net/network/IPv4.inc +++ b/kernel/branches/net/network/IPv4.inc @@ -172,10 +172,10 @@ IPv4_handler: ; TODO: implement handler for IP options cmp [edx + IPv4_Packet.DestinationAddress], -1 je .ip_ok -; ; maybe it's a multicast then -; -; mov eax, [edx + IPv4_Packet.DestinationAddress] -; and eax, 0xff000000 + ; maybe it's a multicast then + + mov eax, [edx + IPv4_Packet.DestinationAddress] + and eax, 0xff000000 ; cmp eax, 224 shl 24 ; je .ip_ok diff --git a/kernel/branches/net/network/ethernet.inc b/kernel/branches/net/network/ethernet.inc index 936aaddcdb..6f3309e1ec 100644 --- a/kernel/branches/net/network/ethernet.inc +++ b/kernel/branches/net/network/ethernet.inc @@ -16,8 +16,6 @@ $Revision$ -ETH_QUEUE_SIZE equ 16 - struct ETH_FRAME .DstMAC dp ? ; destination MAC-address .SrcMAC dp ? ; source MAC-address @@ -28,20 +26,14 @@ ends virtual at NET_DEVICE.end ETH_DEVICE: - .unload dd ? - .reset dd ? - .transmit dd ? - .set_MAC dd ? - .get_MAC dd ? + .set_mode dd ? .get_mode dd ? - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? + .set_MAC dd ? + .get_MAC dd ? + .mode dd ? - .name dd ? .mac dp ? end virtual @@ -108,6 +100,9 @@ ETH_receiver: cmp ax, ETHER_ARP je ARP_handler +; cmp ax, ETHER_PPP_DISCOVERY +; je PPPOE_discovery + DEBUGF 2,"Unknown ethernet packet type %x\n", ax .dump: @@ -138,7 +133,10 @@ ETH_create_packet: DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx - cmp ecx, 1500 ;;; + push esi + mov esi, [NET_DRV_LIST] ;;; TODO: FIXME + cmp ecx, [esi + NET_DEVICE.mtu] + pop esi jg .exit push ecx di eax ebx edx @@ -171,7 +169,7 @@ ETH_create_packet: mov ebx, [NET_DRV_LIST + ebx] cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes - jg .continue + jge .continue mov edx, 46 + ETH_FRAME.Data .continue: @@ -240,23 +238,23 @@ ETH_API: ret .packets_tx: - mov eax, dword [eax + ETH_DEVICE.packets_tx] + mov eax, dword [eax + NET_DEVICE.packets_tx] ret .packets_rx: - mov eax, dword [eax + ETH_DEVICE.packets_rx] + mov eax, dword [eax + NET_DEVICE.packets_rx] ret .bytes_tx: - mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4] - mov eax, dword [eax + ETH_DEVICE.bytes_tx] + mov ebx, dword [eax + NET_DEVICE.bytes_tx + 4] + mov eax, dword [eax + NET_DEVICE.bytes_tx] mov [esp+20+4], ebx ; TODO: fix this ugly code ret .bytes_rx: - mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4] - mov eax, dword [eax + ETH_DEVICE.bytes_rx] + mov ebx, dword [eax + NET_DEVICE.bytes_rx + 4] + mov eax, dword [eax + NET_DEVICE.bytes_rx] mov [esp+20+4], ebx ; TODO: fix this ugly code ret @@ -270,8 +268,7 @@ ETH_API: .write_mac: push ecx push dx - mov eax, [eax + ETH_DEVICE.set_MAC] - call eax + call [eax + ETH_DEVICE.set_MAC] ret .in_queue: diff --git a/kernel/branches/net/network/icmp.inc b/kernel/branches/net/network/icmp.inc index c0dbd26058..ddcea7c90f 100644 --- a/kernel/branches/net/network/icmp.inc +++ b/kernel/branches/net/network/icmp.inc @@ -209,8 +209,8 @@ ICMP_input: pop ecx edx ebx mov word [edx + ICMP_Packet.Checksum], ax - jmp NET_send ; Send the reply - ; and return to caller of this proc + call [ebx + NET_DEVICE.transmit] + ret @@ -251,7 +251,7 @@ ICMP_input: add esp, 4 sub edx, esi mov edi, edx -;;; jmp SOCKET_input + jmp SOCKET_input .dump: DEBUGF 1,"ICMP_Handler - dumping\n" @@ -264,24 +264,22 @@ ICMP_input: ;----------------------------------------------------------------- ; -; Note: ICMP only works on top of IP protocol :) +; ICMP_output ; -; inputs: -; -; eax = dest ip -; ebx = source ip -; ecx = data length -; dh = type -; dl = code -; high 16 bits of edx = fragment id (for IP header) -; esi = data offset -; edi = identifier shl 16 + sequence number +; IN: eax = dest ip +; ebx = source ip +; ecx = data length +; dh = type +; dl = code +; high 16 bits of edx = fragment id (for IP header) +; esi = data offset +; edi = identifier shl 16 + sequence number ; ;----------------------------------------------------------------- align 4 ICMP_output: - DEBUGF 1,"Create ICMP Packet\n" + DEBUGF 1,"Creating ICMP Packet\n" push esi edi edx @@ -292,7 +290,7 @@ ICMP_output: call IPv4_create_packet jz .exit - DEBUGF 1,"full icmp packet size: %u\n", edx + DEBUGF 1,"full icmp packet size: %u\n", edx pop eax mov word [edi + ICMP_Packet.Type], ax ; Write both type and code bytes at once @@ -320,13 +318,12 @@ ICMP_output: rep movsb sub edi, edx ;;; TODO: find a better way to remember start of packet - mov ecx, [ebx + ETH_DEVICE.transmit] - push edx edi ecx - DEBUGF 1,"Sending ICMP Packet\n" - ret ; Send the packet (create_packet routine outputs pointer to routine to send packet in eax) - + push edx edi + DEBUGF 1,"Sending ICMP Packet\n" + call [ebx + NET_DEVICE.transmit] + ret .exit: - DEBUGF 1,"Creating ICMP Packet failed\n" + DEBUGF 1,"Creating ICMP Packet failed\n" add esp, 3*4 ret diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index d9863625e7..281d515ba5 100644 --- a/kernel/branches/net/network/socket.inc +++ b/kernel/branches/net/network/socket.inc @@ -74,7 +74,6 @@ virtual at IP_SOCKET.end .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) .t_state dd ? ; TCB state - .t_timer dd ? ; TCB timer (seconds) .t_rxtshift dd ? .t_rxtcur dd ? .t_dupacks dd ? @@ -144,6 +143,16 @@ virtual at IP_SOCKET.end .ts_recent_age dd ? .last_ack_sent dd ? + +;------- +; Timers + + .timer_retransmission dw ? ; rexmt + .timer_ack dw ? + .timer_persist dw ? + .timer_keepalive dw ? ; keepalive/syn timeout + .timer_timed_wait dw ? ; also used as 2msl timer + .end: end virtual @@ -335,7 +344,7 @@ SOCKET_bind: jz s_error .got_port: - DEBUGF 1,"using local port: %u", bx + DEBUGF 1,"using local port: %u\n", bx mov word [eax + UDP_SOCKET.LocalPort], bx mov ebx, dword [edx + 4] @@ -391,7 +400,7 @@ SOCKET_connect: mov bx , word [edx + 2] mov word [eax + UDP_SOCKET.RemotePort], bx mov [eax + UDP_SOCKET.firstpacket], 0 - DEBUGF 1,"remote port: %u ",bx + DEBUGF 1,"remote port: %u\n",bx mov ebx, dword [edx + 4] mov dword [eax + IP_SOCKET.RemoteIP], ebx @@ -408,6 +417,8 @@ SOCKET_connect: add [TCP_sequence_num], 6400 mov [eax + TCP_SOCKET.ISS], ebx + mov [eax + TCP_SOCKET.timer_keepalive], 120 ; 120*630ms => 75,6 seconds + lea ebx, [eax + SOCKET.lock] call wait_mutex @@ -417,7 +428,7 @@ SOCKET_connect: mov bx , word [edx + 2] mov [eax + TCP_SOCKET.RemotePort], bx - DEBUGF 1,"remote port: %u ",bx + DEBUGF 1,"remote port: %u\n", bx mov ebx, dword [edx + 4] mov [eax + IP_SOCKET.RemoteIP], ebx @@ -435,6 +446,8 @@ SOCKET_connect: call SOCKET_find_port @@: + DEBUGF 1,"remote port: %u\n", [eax + TCP_SOCKET.LocalPort]:2 + ; mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT call TCP_output diff --git a/kernel/branches/net/network/stack.inc b/kernel/branches/net/network/stack.inc index f075172afb..856160ee8b 100644 --- a/kernel/branches/net/network/stack.inc +++ b/kernel/branches/net/network/stack.inc @@ -35,8 +35,10 @@ MIN_EPHEMERAL_PORT equ 49152 MAX_EPHEMERAL_PORT equ 61000 ; Ethernet protocol numbers -ETHER_ARP equ 0x0608 -ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel +ETHER_ARP equ 0x0608 +ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel +ETHER_PPP_DISCOVERY equ 0x6388 +ETHER_PPP_SESSION equ 0x6488 ;Protocol family AF_UNSPEC equ 0 @@ -76,7 +78,20 @@ NET_TYPE_SLIP equ 2 virtual at 0 NET_DEVICE: - .type dd ? + + .type dd ? ; Type field + .mtu dd ? ; Maximal Transmission Unit + .name dd ? ; Ptr to 0 terminated string + + .unload dd ? ; Ptrs to driver functions + .reset dd ? ; + .transmit dd ? ; + + .bytes_tx dq ? ; Statistics, updated by the driver + .bytes_rx dq ? ; + .packets_tx dd ? ; + .packets_rx dd ? ; + .end: end virtual @@ -193,26 +208,17 @@ stack_handler: je .exit mov [net_10ms], eax - if ETH_QUEUE - call ETH_handler - call ETH_send_queued - end if - call TCP_10ms + test [net_10ms], 0x0f ; 160ms + jnz .exit - inc [net_tmr_count] - cmp [net_tmr_count], 50 - je .500ms - cmp [net_tmr_count], 100 - jne .exit +; call TCP_timer_160ms + test [net_10ms], 0x3f ; 640ms + jnz .exit + +; call TCP_timer_640ms call ARP_decrease_entry_ttls call IPv4_decrease_fragment_ttls - call TCP_timer_1000ms - - mov [net_tmr_count], 0 - - .500ms: - call TCP_500ms .exit: ret @@ -380,34 +386,6 @@ NET_ptr_to_num: pop ecx ret - - - -;-------------------------- -; -; NET_send -; -; IN: ebx = ptr to device struct -; [esp] = data ptr -; [esp + 4] = data size -; -; OUT: / -; -;-------------------------- -align 4 -NET_send: - - call [ebx + ETH_DEVICE.transmit] ;;;; - -;;; TODO:check if packet was sent ok - - call kernel_free - add esp, 4 - ret - - - - ;----------------------------------------------------------------- ; ; checksum_1 @@ -563,7 +541,7 @@ sys_network: jnz @f mov esi, [esi + NET_DRV_LIST] - mov esi, [esi + ETH_DEVICE.name] + mov esi, [esi + NET_DEVICE.name] mov edi, ecx mov ecx, 64 ; max length @@ -578,7 +556,7 @@ sys_network: jnz @f mov esi, [esi + NET_DRV_LIST] - call [esi + ETH_DEVICE.reset] + call [esi + NET_DEVICE.reset] jmp .return @@: @@ -587,7 +565,7 @@ sys_network: jnz @f mov esi, [esi + NET_DRV_LIST] - call [esi + ETH_DEVICE.unload] + call [esi + NET_DEVICE.unload] jmp .return @@: @@ -645,13 +623,13 @@ sys_protocols: cmp ax , ETHER_ARP je ARP_API - cmp ax , 1337 + cmp ax , 1337 ;;;;; je ETH_API add esp, 4 ; if we reached here, no function was called, so we need to balance stack .doesnt_exist: - DEBUGF 1,"sys_protocols: protocol %u doesnt exist on device %u!\n",ax, bh + DEBUGF 1,"sys_protocols: protocol %u doesnt exist on device %u!\n", ax, bh mov eax, -1 .return: diff --git a/kernel/branches/net/network/tcp.inc b/kernel/branches/net/network/tcp.inc index e538af3c2a..54830ed564 100644 --- a/kernel/branches/net/network/tcp.inc +++ b/kernel/branches/net/network/tcp.inc @@ -58,6 +58,22 @@ TCP_OPT_MAXSEG equ 2 ; Maximum Segment Size. TCP_OPT_WINDOW equ 3 ; window scale TCP_OPT_TIMESTAMP equ 8 +; Fundamental timer values +TCP_time_MSL equ 47 ; max segment lifetime (30s) +TCP_time_re_min equ 2 ; min retransmission (1,28s) +TCP_time_re_max equ 100 ; max retransmission (64s) +TCP_time_pers_min equ 8 ; min persist (5,12s) +TCP_time_pers_max equ 94 ; max persist (60,16s) +TCP_time_keep_init equ 118 ; connectione stablishment (75,52s) +TCP_time_keep_idle equ 4608 ; idle time before 1st probe (2h) +TCP_time_keep_interval equ 118 ; between probes when no response (75,52s) +TCP_time_rtt_default equ 5 ; default Round Trip Time (3,2s) + +; timer constants +TCP_max_rxtshift equ 12 ; max retransmissions waiting for ACK +TCP_max_keepcnt equ 8 ; max keepalive probes + + struct TCP_segment .SourcePort dw ? .DestinationPort dw ? @@ -113,24 +129,56 @@ TCP_init: mov ecx, (6*IP_MAX_INTERFACES) rep stosd - mov [TCP_sequence_num],1 + mov [TCP_sequence_num], 1 + + ret + + +;---------------------- +; +; +;---------------------- +align 4 +TCP_timer_160ms: + + mov eax, net_sockets + .loop: + mov eax, [eax + SOCKET.NextPtr] + or eax, eax + jz .exit + + cmp [eax + SOCKET.Type], IP_PROTO_TCP + jne .loop + + dec [eax + TCP_SOCKET.timer_ack] + jnz .loop + + DEBUGF 1,"TCP ack for socket %x expired, time to piggyback!\n", eax + + push eax + call TCP_respond + pop eax + + jmp .loop + + .exit: ret ;----------------------------------------------------------------- ; -; decrease socket ttls -; -; IN: / -; OUT: / -; -; destroys: eax ; ;----------------------------------------------------------------- align 4 -TCP_timer_1000ms: -; scan through all the active TCP sockets, decrementing active timers +TCP_timer_640ms: + +; Update TCP sequence number + + add [TCP_sequence_num], 64000 + +; scan through all the active TCP sockets, decrementing ALL timers +; timers do not have the chance to wrap because of the keepalive timer will kill the socket when it expires mov eax, net_sockets .loop: @@ -142,62 +190,40 @@ TCP_timer_1000ms: cmp [eax + SOCKET.Type], IP_PROTO_TCP jne .loop - cmp [eax + TCP_SOCKET.t_timer], 0 - jne .decrement_tcb - ;;;;;; cmp [eax + TCP_SOCKET.wndsizeTimer], 0 - jne .decrement_wnd - jmp .loop + dec [eax + TCP_SOCKET.timer_retransmission] + jnz .check_more2 - .decrement_tcb: -; decrement it, delete socket if TCB timer = 0 & socket in timewait state - dec [eax + TCP_SOCKET.t_timer] + DEBUGF 1,"socket %x: Retransmission timer expired\n", eax + + push eax + call TCP_output + pop eax + + .check_more2: + dec [eax + TCP_SOCKET.timer_keepalive] + jnz .check_more3 + + DEBUGF 1,"socket %x: Keepalive expired\n", eax + + ;;; TODO: check socket state and handle accordingly + + .check_more3: + dec [eax + TCP_SOCKET.timer_timed_wait] + jnz .check_more5 + + DEBUGF 1,"socket %x: 2MSL timer expired\n", eax + + .check_more5: + dec [eax + TCP_SOCKET.timer_persist] jnz .loop - cmp [eax + TCP_SOCKET.t_state], TCB_TIMED_WAIT - jne .loop - - push [eax + SOCKET.NextPtr] - call SOCKET_free - pop eax - jmp .check_only - - .decrement_wnd: -;;;;;; dec [eax + TCP_SOCKET.wndsizeTimer] + DEBUGF 1,"socket %x: persist timer expired\n", eax + jmp .loop .exit: ret - -;---------------------- -; -; TCP_500ms -; -;---------------------- -align 4 -TCP_500ms: - - add [TCP_sequence_num], 64000 - - ret - - - -;---------------------- -; -; TCP_10ms -; -;---------------------- -align 4 -TCP_10ms: - - ; todo: decrease timers - - ret - - - - ;----------------------------------------------------------------- ; ; TCP_input: @@ -374,8 +400,9 @@ TCP_input: ;------------------------------------- ; Reset idle timer and keepalive timer + ;;;; TODO: idle timer? -; TODO + mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;----------------------------------------- ; Process TCP options if not in LISTEN state @@ -475,13 +502,14 @@ TCP_input: ; Delete acknowledged bytes from send buffer ; Stop retransmit timer + mov [ebx + TCP_SOCKET.timer_ack], 0 ; Awaken waiting processes + mov eax, ebx + call SOCKET_notify_owner ; Generate more output - - - + call TCP_output jmp .drop @@ -518,8 +546,9 @@ TCP_input: add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Add the data to the socket buffer - -; The receiving process is awakened (by sorwakeup). + mov eax, ebx + ;;; mov... + call SOCKET_input ; The delayed-ACK flag is set and the input processing is complete. @@ -679,8 +708,8 @@ align 4 jle @f mov [ebx + TCP_SOCKET.SND_NXT], eax - -; TODO: turn off retransmission timer + mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval + mov [ebx + TCP_SOCKET.timer_retransmission], 0 mov eax, [edx + TCP_segment.SequenceNumber] mov [ebx + TCP_SOCKET.IRS], eax @@ -937,18 +966,6 @@ align 4 jg .ack_dup jl .ack_nodup -; dd .ack_nodup ;TCB_CLOSED -; dd .ack_nodup ;TCB_LISTEN -; dd .ack_nodup ;TCB_SYN_SENT -; dd .ack_syn_rcvd ;TCB_SYN_RECEIVED -; dd .ack_dup ;TCB_ESTABLISHED -; dd .ack_dup ;TCB_CLOSE_WAIT -; dd .ack_dup ;TCB_FIN_WAIT_1 -; dd .ack_dup ;TCB_CLOSING -; dd .ack_dup ;TCB_LAST_ACK -; dd .ack_dup ;TCB_FIN_WAIT_2 -; dd .ack_dup ;TCB_TIMED_WAIT - ;;;;; .ack_dup: @@ -960,7 +977,7 @@ align 4 ;;;; 887 ;------------------------------------------------- -; If the congestion window was infalted to account +; If the congestion window was inflated to account ; for the other side's cached packets, retrace it ;;;; 888 - 902 @@ -971,6 +988,14 @@ align 4 ;;;;; 903 - 926 + mov [ebx + TCP_SOCKET.timer_retransmission], 0 + + mov eax, [ebx + TCP_SOCKET.SND_MAX] + cmp eax, [edx + TCP_segment.AckNumber] + je .all_outstanding + mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value + .all_outstanding: + ;------------------------------------------- ; Open congestion window in response to ACKs @@ -1428,7 +1453,7 @@ TCP_pull_out_of_band: ; ; TCP_output ; -; IN: eax = socket pointer +; IN: eax = socket pointer ;; esi = ptr to data ;; ecx = number of data bytes ; @@ -1614,7 +1639,7 @@ TCP_output: .enter_persist: - DEBUGF 1,"Entering pesist state\n" + DEBUGF 1,"Entering persist state\n" @@ -1748,7 +1773,7 @@ TCP_output: ;;;; jz .fail push edx eax - call NET_send + call [ebx + NET_DEVICE.transmit] ret ;---------------- @@ -1831,12 +1856,9 @@ TCP_output: DEBUGF 1,"Sending TCP Packet to device %x\n", ebx - mov esi, [ebx + ETH_DEVICE.transmit] - + call [ebx + NET_DEVICE.transmit] ret - - ;------------------------- ; ; TCP_outflags @@ -1902,11 +1924,14 @@ TCP_drop: ;--------------------------------------- ; -; TCP_respond +; TCP_ack ; -; The easy way to send a RST/ACK segment +; The easy way to send an ACK/RST/keepalive segment ; ; IN: eax = socket ptr +; -or- +; edx = packet ptr (eax must be 0) +; cl = flags ; ; OUT: / ; @@ -1916,6 +1941,113 @@ TCP_respond: DEBUGF 1,"TCP_respond\n" +;--------------------- +; Create the IP packet + + push cx eax edx + mov ebx, [eax + IP_SOCKET.LocalIP] + mov eax, [eax + IP_SOCKET.RemoteIP] + mov ecx, TCP_segment.Data + mov di , IP_PROTO_TCP + call IPv4_create_packet + test edi, edi + jz .error + +;--------------------------- +; Now fill in the TCP header + + pop ecx + pop esi + + test esi, esi +; jz + + + push edx eax + + push dword .checksum + je .use_segment + jmp .use_socket + +;--------------------- +; Fill in the checksum + + .checksum: + + push [esi + IP_SOCKET.LocalIP] + push [esi + IP_SOCKET.RemoteIP] + lea esi, [edi - 20] + xor ecx, ecx + call TCP_checksum + +;-------------------- +; And send the segment + + call [ebx + NET_DEVICE.transmit] + ret + + .error: + DEBUGF 1,"TCP_ack failed\n" + add esp, 4 + + ret + +;--------------------------------------------------- +; Fill in the TCP header by using a received segment + + .use_segment: + + mov ax, [esi + TCP_segment.DestinationPort] + rol ax, 8 + stosw + mov ax, [esi + TCP_segment.SourcePort] + rol ax, 8 + stosw + mov eax, [esi + TCP_segment.AckNumber] + bswap eax + stosd + xor eax, eax + stosd + mov al, 0x50 ; Dataoffset: 20 bytes + stosb + mov al, cl + stosb + mov ax, 1280 + rol ax, 8 + stosw ; window + xor eax, eax + stosd ; checksum + urgentpointer + + ret + + +;----------------------------------------------- +; Fill in the TCP header by using the socket ptr + + .use_socket: + + mov ax, [esi + TCP_SOCKET.LocalPort] + rol ax, 8 + stosw + mov ax, [esi + TCP_SOCKET.RemotePort] + rol ax, 8 + stosw + mov eax, [esi + TCP_SOCKET.SND_NXT] + bswap eax + stosd + mov eax, [esi + TCP_SOCKET.RCV_NXT] + bswap eax + stosd + mov al, 0x50 ; Dataoffset: 20 bytes + stosb + mov al, cl + stosb + mov ax, [esi + TCP_SOCKET.RCV_WND] + rol ax, 8 + stosw ; window + xor eax, eax + stosd ; checksum + urgentpointer + ret diff --git a/kernel/branches/net/network/udp.inc b/kernel/branches/net/network/udp.inc index bf7f0b479f..c258c2ca07 100644 --- a/kernel/branches/net/network/udp.inc +++ b/kernel/branches/net/network/udp.inc @@ -252,8 +252,8 @@ UDP_output: DEBUGF 1,"Sending UDP Packet to device %x\n", ebx - jmp NET_send - + call [ebx + NET_DEVICE.transmit] + ret .fail: add esp, 8+8 ret