diff --git a/kernel/trunk/build.bat b/kernel/trunk/build.bat index bf24da24ec..671f296168 100644 --- a/kernel/trunk/build.bat +++ b/kernel/trunk/build.bat @@ -52,7 +52,7 @@ goto :eof if not exist bin mkdir bin echo lang fix %lang% > lang.inc - fasm kernel.asm bin\kernel.mnt + fasm -m 65536 kernel.asm bin\kernel.mnt if not %errorlevel%==0 goto :Error_FasmFailed erase lang.inc goto :eof @@ -72,7 +72,7 @@ goto :eof if not exist bin\drivers mkdir bin\drivers cd drivers for %%a in (%drivers%) do ( - fasm %%a.asm ..\bin\drivers\%%a.obj + fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj if not %errorlevel%==0 goto :Error_FasmFailed ) cd .. @@ -84,7 +84,7 @@ goto :eof if not exist bin\skins mkdir bin\skins cd skin - fasm default.asm ..\bin\skins\default.skn + fasm -m 65536 default.asm ..\bin\skins\default.skn if not %errorlevel%==0 goto :Error_FasmFailed cd .. goto :eof diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index b822d95128..9d3383b03a 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -4374,7 +4374,7 @@ sys_msg_board_str: ret uglobal - msg_board_data: times 512 db 0 + msg_board_data: times 4096 db 0 msg_board_count dd 0x0 endg @@ -4390,7 +4390,7 @@ sys_msg_board: mov [msg_board_data+ecx],bl inc ecx - and ecx, 511 + and ecx, 4095 mov [msg_board_count], ecx mov [check_idle_semaphore], 5 ret diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index 3303245224..6759bd15b2 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -75,30 +75,30 @@ end if } ; \end{diamond}[29.09.2006] -struc db [a] { common . db a - if ~used . - display 'not used db: ',`.,13,10 - end if } -struc dw [a] { common . dw a - if ~used . - display 'not used dw: ',`.,13,10 - end if } -struc dd [a] { common . dd a - if ~used . - display 'not used dd: ',`.,13,10 - end if } -struc dp [a] { common . dp a - if ~used . - display 'not used dp: ',`.,13,10 - end if } -struc dq [a] { common . dq a - if ~used . - display 'not used dq: ',`.,13,10 - end if } -struc dt [a] { common . dt a - if ~used . - display 'not used dt: ',`.,13,10 - end if } +;struc db [a] { common . db a +; if ~used . +; display 'not used db: ',`.,13,10 +; end if } +;struc dw [a] { common . dw a +; if ~used . +; display 'not used dw: ',`.,13,10 +; end if } +;struc dd [a] { common . dd a +; if ~used . +; display 'not used dd: ',`.,13,10 +; end if } +;struc dp [a] { common . dp a +; if ~used . +; display 'not used dp: ',`.,13,10 +; end if } +;struc dq [a] { common . dq a +; if ~used . +; display 'not used dq: ',`.,13,10 +; end if } +;struc dt [a] { common . dt a +; if ~used . +; display 'not used dt: ',`.,13,10 +; end if } struc RECT { .left dd ? diff --git a/kernel/trunk/network/eth_drv/drivers/rtl8139.inc b/kernel/trunk/network/eth_drv/drivers/rtl8139.inc index 8c5f90c405..cb938da187 100644 --- a/kernel/trunk/network/eth_drv/drivers/rtl8139.inc +++ b/kernel/trunk/network/eth_drv/drivers/rtl8139.inc @@ -177,7 +177,7 @@ rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_ uglobal align 4 rtl8139_rx_buff_offset: dd 0 -curr_tx_desc: dd 0 +curr_tx_desc dd 0 endg iglobal @@ -442,8 +442,8 @@ rtl8139_read_eeprom: ; 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 +; Size of packet in ecx +; Pointer to packet data in esi ; Destroyed registers ; eax, edx, esi, edi ; ToDo diff --git a/kernel/trunk/network/eth_drv/drivers/rtl8169.inc b/kernel/trunk/network/eth_drv/drivers/rtl8169.inc new file mode 100644 index 0000000000..999f870f07 --- /dev/null +++ b/kernel/trunk/network/eth_drv/drivers/rtl8169.inc @@ -0,0 +1,1204 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; RTL8169.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.1 11 February 2007 ;; +;; ;; +;; Driver for chips of RealTek 8169 family ;; +;; References: ;; +;; r8169.c - linux driver (etherboot project) ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; Copyright 2007 mike.dld, ;; +;; mike.dld@gmail.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ETH_ALEN equ 6 + ETH_HLEN equ (2 * ETH_ALEN + 2) + ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length + + RTL8169_REG_MAC0 equ 0x0 ; Ethernet hardware address + RTL8169_REG_MAR0 equ 0x8 ; Multicast filter + RTL8169_REG_TxDescStartAddr equ 0x20 + RTL8169_REG_TxHDescStartAddr equ 0x28 + RTL8169_REG_FLASH equ 0x30 + RTL8169_REG_ERSR equ 0x36 + RTL8169_REG_ChipCmd equ 0x37 + RTL8169_REG_TxPoll equ 0x38 + RTL8169_REG_IntrMask equ 0x3C + RTL8169_REG_IntrStatus equ 0x3E + RTL8169_REG_TxConfig equ 0x40 + RTL8169_REG_RxConfig equ 0x44 + RTL8169_REG_RxMissed equ 0x4C + RTL8169_REG_Cfg9346 equ 0x50 + RTL8169_REG_Config0 equ 0x51 + RTL8169_REG_Config1 equ 0x52 + RTL8169_REG_Config2 equ 0x53 + RTL8169_REG_Config3 equ 0x54 + RTL8169_REG_Config4 equ 0x55 + RTL8169_REG_Config5 equ 0x56 + RTL8169_REG_MultiIntr equ 0x5C + RTL8169_REG_PHYAR equ 0x60 + RTL8169_REG_TBICSR equ 0x64 + RTL8169_REG_TBI_ANAR equ 0x68 + RTL8169_REG_TBI_LPAR equ 0x6A + RTL8169_REG_PHYstatus equ 0x6C + RTL8169_REG_RxMaxSize equ 0xDA + RTL8169_REG_CPlusCmd equ 0xE0 + RTL8169_REG_RxDescStartAddr equ 0xE4 + RTL8169_REG_ETThReg equ 0xEC + RTL8169_REG_FuncEvent equ 0xF0 + RTL8169_REG_FuncEventMask equ 0xF4 + RTL8169_REG_FuncPresetState equ 0xF8 + RTL8169_REG_FuncForceEvent equ 0xFC + + ; InterruptStatusBits + RTL8169_ISB_SYSErr equ 0x8000 + RTL8169_ISB_PCSTimeout equ 0x4000 + RTL8169_ISB_SWInt equ 0x0100 + RTL8169_ISB_TxDescUnavail equ 0x80 + RTL8169_ISB_RxFIFOOver equ 0x40 + RTL8169_ISB_LinkChg equ 0x20 + RTL8169_ISB_RxOverflow equ 0x10 + RTL8169_ISB_TxErr equ 0x08 + RTL8169_ISB_TxOK equ 0x04 + RTL8169_ISB_RxErr equ 0x02 + RTL8169_ISB_RxOK equ 0x01 + + ; RxStatusDesc + RTL8169_SD_RxRES equ 0x00200000 + RTL8169_SD_RxCRC equ 0x00080000 + RTL8169_SD_RxRUNT equ 0x00100000 + RTL8169_SD_RxRWT equ 0x00400000 + + ; ChipCmdBits + RTL8169_CMD_Reset equ 0x10 + RTL8169_CMD_RxEnb equ 0x08 + RTL8169_CMD_TxEnb equ 0x04 + RTL8169_CMD_RxBufEmpty equ 0x01 + + ; Cfg9346Bits + RTL8169_CFG_9346_Lock equ 0x00 + RTL8169_CFG_9346_Unlock equ 0xC0 + + ; rx_mode_bits + RTL8169_RXM_AcceptErr equ 0x20 + RTL8169_RXM_AcceptRunt equ 0x10 + RTL8169_RXM_AcceptBroadcast equ 0x08 + RTL8169_RXM_AcceptMulticast equ 0x04 + RTL8169_RXM_AcceptMyPhys equ 0x02 + RTL8169_RXM_AcceptAllPhys equ 0x01 + + ; RxConfigBits + RTL8169_RXC_FIFOShift equ 13 + RTL8169_RXC_DMAShift equ 8 + + ; TxConfigBits + RTL8169_TXC_InterFrameGapShift equ 24 + RTL8169_TXC_DMAShift equ 8 ; DMA burst value (0-7) is shift this many bits + + ; rtl8169_PHYstatus + RTL8169_PHYS_TBI_Enable equ 0x80 + RTL8169_PHYS_TxFlowCtrl equ 0x40 + RTL8169_PHYS_RxFlowCtrl equ 0x20 + RTL8169_PHYS_1000bpsF equ 0x10 + RTL8169_PHYS_100bps equ 0x08 + RTL8169_PHYS_10bps equ 0x04 + RTL8169_PHYS_LinkStatus equ 0x02 + RTL8169_PHYS_FullDup equ 0x01 + + ; GIGABIT_PHY_registers + RTL8169_PHY_CTRL_REG equ 0 + RTL8169_PHY_STAT_REG equ 1 + RTL8169_PHY_AUTO_NEGO_REG equ 4 + RTL8169_PHY_1000_CTRL_REG equ 9 + + ; GIGABIT_PHY_REG_BIT + RTL8169_PHY_Restart_Auto_Nego equ 0x0200 + RTL8169_PHY_Enable_Auto_Nego equ 0x1000 + + ; PHY_STAT_REG = 1; + RTL8169_PHY_Auto_Neco_Comp equ 0x0020 + + ; PHY_AUTO_NEGO_REG = 4; + RTL8169_PHY_Cap_10_Half equ 0x0020 + RTL8169_PHY_Cap_10_Full equ 0x0040 + RTL8169_PHY_Cap_100_Half equ 0x0080 + RTL8169_PHY_Cap_100_Full equ 0x0100 + + ; PHY_1000_CTRL_REG = 9; + RTL8169_PHY_Cap_1000_Full equ 0x0200 + RTL8169_PHY_Cap_1000_Half equ 0x0100 + + RTL8169_PHY_Cap_PAUSE equ 0x0400 + RTL8169_PHY_Cap_ASYM_PAUSE equ 0x0800 + + RTL8169_PHY_Cap_Null equ 0x0 + + ; _MediaType + RTL8169_MT_10_Half equ 0x01 + RTL8169_MT_10_Full equ 0x02 + RTL8169_MT_100_Half equ 0x04 + RTL8169_MT_100_Full equ 0x08 + RTL8169_MT_1000_Full equ 0x10 + + ; _TBICSRBit + RTL8169_TBI_LinkOK equ 0x02000000 + + ; _DescStatusBit + RTL8169_DSB_OWNbit equ 0x80000000 + RTL8169_DSB_EORbit equ 0x40000000 + RTL8169_DSB_FSbit equ 0x20000000 + RTL8169_DSB_LSbit equ 0x10000000 + +; MAC address length +MAC_ADDR_LEN equ 6 + +; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) +MAX_ETH_FRAME_SIZE equ 1536 + +TX_FIFO_THRESH equ 256 ; In bytes + +RX_FIFO_THRESH equ 7 ; 7 means NO threshold, Rx buffer level before first PCI xfer +RX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 +TX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 +ETTh equ 0x3F ; 0x3F means NO threshold + +EarlyTxThld equ 0x3F ; 0x3F means NO early transmit +RxPacketMaxSize equ 0x0800 ; Maximum size supported is 16K-1 +InterFrameGap equ 0x03 ; 3 means InterFrameGap = the shortest one + +NUM_TX_DESC equ 1 ; Number of Tx descriptor registers +NUM_RX_DESC equ 4 ; Number of Rx descriptor registers +RX_BUF_SIZE equ 1536 ; Rx Buffer size + +HZ equ 1000 + +RTL_MIN_IO_SIZE equ 0x80 +TX_TIMEOUT equ (6*HZ) + +RTL8169_TIMER_EXPIRE_TIME equ 100 + +ETH_HDR_LEN equ 14 +DEFAULT_MTU equ 1500 +DEFAULT_RX_BUF_LEN equ 1536 + + +;#ifdef RTL8169_JUMBO_FRAME_SUPPORT +;#define MAX_JUMBO_FRAME_MTU ( 10000 ) +;#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) +;#else +MAX_RX_SKBDATA_SIZE equ 1600 +;#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +;#ifdef RTL8169_USE_IO +;!!!#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) +macro RTL_W8 reg,val8 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val8 eq al + mov al,val8 + end if + out dx,al +} +;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) +macro RTL_W16 reg,val16 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val16 eq ax + mov ax,val16 + end if + out dx,ax +} +;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) +macro RTL_W32 reg,val32 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val32 eq eax + mov eax,val32 + end if + out dx,eax +} +;!!!#define RTL_R8(reg) inb (ioaddr + (reg)) +macro RTL_R8 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in al,dx +} +;!!!#define RTL_R16(reg) inw (ioaddr + (reg)) +macro RTL_R16 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in ax,dx +} +;!!!#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) +macro RTL_R32 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in eax,dx +} +;#else +; write/read MMIO register +;#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) +;#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) +;#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) +;#define RTL_R8(reg) readb (ioaddr + (reg)) +;#define RTL_R16(reg) readw (ioaddr + (reg)) +;#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) +;#endif + +MCFG_METHOD_01 equ 0x01 +MCFG_METHOD_02 equ 0x02 +MCFG_METHOD_03 equ 0x03 +MCFG_METHOD_04 equ 0x04 +MCFG_METHOD_05 equ 0x05 +MCFG_METHOD_11 equ 0x0b +MCFG_METHOD_12 equ 0x0c +MCFG_METHOD_13 equ 0x0d +MCFG_METHOD_14 equ 0x0e +MCFG_METHOD_15 equ 0x0f + +PCFG_METHOD_1 equ 0x01 ; PHY Reg 0x03 bit0-3 == 0x0000 +PCFG_METHOD_2 equ 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001 +PCFG_METHOD_3 equ 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002 + +PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space +PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space +PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits +PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles +PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate +PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping +PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking +PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping +PCI_COMMAND_SERR equ 0x100 ; Enable SERR +PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes + +struc rtl8169_TxDesc { + .status dd ? + .vlan_tag dd ? + .buf_addr dd ? + .buf_Haddr dd ? +} +virtual at 0 + rtl8169_TxDesc rtl8169_TxDesc + sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc +end virtual + +struc rtl8169_RxDesc { + .status dd ? + .vlan_tag dd ? + .buf_addr dd ? + .buf_Haddr dd ? +} +virtual at 0 + rtl8169_RxDesc rtl8169_RxDesc + sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc +end virtual + +virtual at eth_data_start + +; Define the TX Descriptor +align 256 +rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc + +; Create a static buffer of size RX_BUF_SZ for each +; TX Descriptor. All descriptors point to a +; part of this buffer +align 256 +rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE + +; Define the RX Descriptor +align 256 +rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc + +; Create a static buffer of size RX_BUF_SZ for each +; RX Descriptor All descriptors point to a +; part of this buffer +align 256 +rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE + +rtl8169_tpc: + .mmio_addr dd ? ; memory map physical address + .chipset dd ? + .pcfg dd ? + .mcfg dd ? + .cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt + .cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt + .TxDescArrays dd ? ; Index of Tx Descriptor buffer + .RxDescArrays dd ? ; Index of Rx Descriptor buffer + .TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer + .RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer + .RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array + .Tx_skbuff rd NUM_TX_DESC + +end virtual + +rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK +rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E + +iglobal + +;static struct { +; const char *name; +; u8 mcfg; /* depend on RTL8169 docs */ +; u32 RxConfigMask; /* should clear the bits supported by this chip */ +;} +rtl_chip_info dd \ + MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169 + MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s + MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s + MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb + MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc + MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E + MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E + MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e // PCI-E 8139 + MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e // PCI-E 8139 + MCFG_METHOD_15, 0xff7e1880 ; RTL8100e // PCI-E 8139 + +mac_info dd \ + 0x38800000, MCFG_METHOD_15, \ + 0x38000000, MCFG_METHOD_12, \ + 0x34000000, MCFG_METHOD_13, \ + 0x30800000, MCFG_METHOD_14, \ + 0x30000000, MCFG_METHOD_11, \ + 0x18000000, MCFG_METHOD_05, \ + 0x10000000, MCFG_METHOD_04, \ + 0x04000000, MCFG_METHOD_03, \ + 0x00800000, MCFG_METHOD_02, \ + 0x00000000, MCFG_METHOD_01 ; catch-all + +endg + +PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space +PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space +PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits +PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles +PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate +PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping +PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking +PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping +PCI_COMMAND_SERR equ 0x100 ; Enable SERR +PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes + +PCI_VENDOR_ID equ 0x00 ; 16 bits +PCI_DEVICE_ID equ 0x02 ; 16 bits +PCI_COMMAND equ 0x04 ; 16 bits + +PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits +PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits +PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits +PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits +PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits +PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits + +PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 +PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address +PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] +PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address + +PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) +PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) +PCI_BASE_ADDRESS_SPACE_IO equ 0x01 +PCI_ROM_ADDRESS equ 0x30 ; 32 bits + +proc CONFIG_CMD,where:byte + movzx eax,byte[pci_bus] + shl eax,8 + mov al,[pci_dev] + shl eax,8 + mov al,[where] + and al,not 3 + or eax,0x80000000 + ret +endp + +proc pci_read_config_byte,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,3 + add edx,0xCFC + in al,dx + pop edx + ret +endp + +proc pci_read_config_word,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,2 + add edx,0xCFC + in ax,dx + pop edx + ret +endp + +proc pci_read_config_dword,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov edx,0xCF8 + out dx,eax + mov edx,0xCFC + in eax,dx + pop edx + ret +endp + +proc pci_write_config_byte,where:dword,value:byte + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,3 + add edx,0xCFC + mov al,[value] + out dx,al + pop edx + ret +endp + +proc pci_write_config_word,where:dword,value:word + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,2 + add edx,0xCFC + mov ax,[value] + out dx,ax + pop edx + ret +endp + +proc pci_write_config_dword,where:dword,value:dword + push edx + stdcall CONFIG_CMD,[where] + mov edx,0xCF8 + out dx,eax + mov edx,0xCFC + mov eax,[value] + out dx,eax + pop edx + ret +endp + +; Set device to be a busmaster in case BIOS neglected to do so. +; Also adjust PCI latency timer to a reasonable value, 32. +proc adjust_pci_device + + DEBUGF 1,"K : adjust_pci_device\n" + + stdcall pci_read_config_word,PCI_COMMAND + mov bx,ax + or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO + cmp ax,bx + je @f + DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2 + stdcall pci_write_config_word,PCI_COMMAND,ebx + @@: + stdcall pci_read_config_byte,PCI_LATENCY_TIMER + cmp al,32 + jae @f + DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al + stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32 + @@: + ret +endp + +; Find the start of a pci resource +proc pci_bar_start,index:dword + stdcall pci_read_config_dword,[index] + test eax,PCI_BASE_ADDRESS_SPACE_IO + jz @f + and eax,PCI_BASE_ADDRESS_IO_MASK + jmp .exit + @@: push eax + and eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK + cmp eax,PCI_BASE_ADDRESS_MEM_TYPE_64 + jne .not64 + mov eax,[index] + add eax,4 + stdcall pci_read_config_dword,eax + or eax,eax + jz .not64 + DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n" + add esp,4 + or eax,-1 + ret + .not64: + pop eax + and eax,PCI_BASE_ADDRESS_MEM_MASK + .exit: + ret +endp + +proc rtl8169_init_board + + DEBUGF 1,"K : rtl8169_init_board\n" + + call adjust_pci_device + + stdcall pci_bar_start,PCI_BASE_ADDRESS_0 + mov [rtl8169_tpc.mmio_addr],eax + ; Soft reset the chip + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset + + ; Check that the chip has finished the reset + mov ecx,1000 + @@: RTL_R8 RTL8169_REG_ChipCmd + test al,RTL8169_CMD_Reset + jz @f + stdcall udelay,10 + loop @b + @@: + ; identify config method + RTL_R32 RTL8169_REG_TxConfig + and eax,0x7c800000 + DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax + mov esi,mac_info-8 + @@: add esi,8 + mov ecx,eax + and ecx,[esi] + cmp ecx,[esi] + jne @b + mov eax,[esi+4] + mov [rtl8169_tpc.mcfg],eax + + mov [rtl8169_tpc.pcfg],PCFG_METHOD_3 + stdcall RTL8169_READ_GMII_REG,3 + and al,0x0f + or al,al + jnz @f + mov [rtl8169_tpc.pcfg],PCFG_METHOD_1 + jmp .pconf + @@: dec al + jnz .pconf + mov [rtl8169_tpc.pcfg],PCFG_METHOD_2 + .pconf: + + ; identify chip attached to board + mov ecx,10 + mov eax,[rtl8169_tpc.mcfg] + @@: dec ecx + js @f + cmp eax,[rtl_chip_info+ecx*8] + jne @b + mov [rtl8169_tpc.chipset],ecx + jmp .match + @@: + ; if unknown chip, assume array element #0, original RTL-8169 in this case + DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n" + RTL_R32 RTL8169_REG_TxConfig + DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax + + mov [rtl8169_tpc.chipset],0 + + xor eax,eax + inc eax + ret + + .match: + xor eax,eax + ret +endp + +proc rtl8169_hw_PHY_config + + DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg] + +; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg); + + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_04 + jne .not_4 +; stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 +; stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e +; stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb +; stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0 + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 + jmp .exit + .not_4: + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + je @f + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jne .not_2_or_3 + @@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 + stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000 + stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1 + stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 + stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 + stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000 + jmp .exit + .not_2_or_3: +; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg); + DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg] + .exit: + ret +endp + +;proc pci_write_config_byte +; ret +;endp + +proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword + + DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value] + + movzx eax,[RegAddr] + shl eax,16 + or eax,[value] + or eax,0x80000000 + RTL_W32 RTL8169_REG_PHYAR,eax + stdcall udelay,1000 + + mov ecx,2000 + ; Check if the RTL8169 has completed writing to the specified MII register + @@: RTL_R32 RTL8169_REG_PHYAR + test eax,0x80000000 + jz .exit + stdcall udelay,100 + loop @b + .exit: + ret +endp + +proc RTL8169_READ_GMII_REG,RegAddr:byte + + DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2 + + push ecx + movzx eax,[RegAddr] + shl eax,16 +; or eax,0x0 + RTL_W32 RTL8169_REG_PHYAR,eax + stdcall udelay,1000 + + mov ecx,2000 + ; Check if the RTL8169 has completed retrieving data from the specified MII register + @@: RTL_R32 RTL8169_REG_PHYAR + test eax,0x80000000 + jnz .exit + stdcall udelay,100 + loop @b + + or eax,-1 + pop ecx + ret + .exit: + RTL_R32 RTL8169_REG_PHYAR + and eax,0xFFFF + pop ecx + ret +endp + +proc rtl8169_set_rx_mode + + DEBUGF 1,"K : rtl8169_set_rx_mode\n" + + ; IFF_ALLMULTI + ; Too many to filter perfectly -- accept all multicasts + RTL_R32 RTL8169_REG_RxConfig + mov ecx,[rtl8169_tpc.chipset] + and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask + or eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys) + RTL_W32 RTL8169_REG_RxConfig,eax + + ; Multicast hash filter + RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff + RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff + ret +endp + +proc rtl8169_init_ring + + DEBUGF 1,"K : rtl8169_init_ring\n" + + xor eax,eax + mov [rtl8169_tpc.cur_rx],eax + mov [rtl8169_tpc.cur_tx],eax + + mov edi,[rtl8169_tpc.TxDescArray] + mov ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4 + cld + rep stosd + mov edi,[rtl8169_tpc.RxDescArray] + mov ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4 + rep stosd + + mov edi,rtl8169_tpc.Tx_skbuff + mov eax,rtl8169_txb + mov ecx,NUM_TX_DESC + @@: stosd + inc eax ; add eax,RX_BUF_SIZE ??? + loop @b + +;!!! for (i = 0; i < NUM_RX_DESC; i++) { +;!!! if (i == (NUM_RX_DESC - 1)) +;!!! tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE; +;!!! else +;!!! tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE; +;!!! tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; +;!!! tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]); +;!!! } + mov esi,rtl8169_tpc.RxBufferRing + mov edi,[rtl8169_tpc.RxDescArray] + mov eax,rtl8169_rxb + mov ecx,NUM_RX_DESC + @@: mov [esi],eax + mov [edi+rtl8169_RxDesc.buf_addr],eax + mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE + add esi,4 + add edi,sizeof.rtl8169_RxDesc + add eax,RX_BUF_SIZE + loop @b + + or [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit + + ret +endp + +proc rtl8169_hw_start + + DEBUGF 1,"K : rtl8169_hw_start\n" + + ; Soft reset the chip + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset + ; Check that the chip has finished the reset + mov ecx,1000 + @@: RTL_R8 RTL8169_REG_ChipCmd + and al,RTL8169_CMD_Reset + jz @f + stdcall udelay,10 + loop @b + @@: + RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb + RTL_W8 RTL8169_REG_ETThReg,ETTh + ; For gigabit rtl8169 + RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize + ; Set Rx Config register + RTL_R32 RTL8169_REG_RxConfig + mov ecx,[rtl8169_tpc.chipset] + and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask + or eax,rtl8169_rx_config + RTL_W32 RTL8169_REG_RxConfig,eax + ; Set DMA burst size and Interframe Gap Time + RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift) + RTL_R16 RTL8169_REG_CPlusCmd + RTL_W16 RTL8169_REG_CPlusCmd,ax + + RTL_R16 RTL8169_REG_CPlusCmd + or ax,1 shl 3 + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + jne @f + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jne @f + or ax,1 shl 14 +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n" + jmp .set + @@:;DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3\n" + .set: RTL_W16 RTL8169_REG_CPlusCmd,ax + +; RTL_W16 0xE2,0x1517 +; RTL_W16 0xE2,0x152a +; RTL_W16 0xE2,0x282a + RTL_W16 0xE2,0x0000 + + MOV [rtl8169_tpc.cur_rx],0 + RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray] + RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray] + RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock + stdcall udelay,10 + RTL_W32 RTL8169_REG_RxMissed,0 + call rtl8169_set_rx_mode + ; no early-rx interrupts + RTL_R16 RTL8169_REG_MultiIntr + and ax,0xF000 + RTL_W16 RTL8169_REG_MultiIntr,ax + RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask + ret +endp + +proc udelay,msec:dword + push esi + mov esi,[msec] + call delay_ms + pop esi + ret +endp + +;*************************************************************************** +; Function +; rtl8169_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 +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +proc rtl8169_probe + + DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + call rtl8169_init_board + + mov ecx,MAC_ADDR_LEN + mov edx,[rtl8169_tpc.mmio_addr] + add edx,RTL8169_REG_MAC0 + xor ebx,ebx + ; Get MAC address. FIXME: read EEPROM + @@: RTL_R8 dx + mov [node_addr+ebx],al + inc edx + inc ebx + loop @b + + DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2 + + ; Config PHY + stdcall rtl8169_hw_PHY_config +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" + RTL_W8 0x82,0x01 + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jae @f +; DEBUGF 1,"K : Set PCI Latency=0x40\n" +; stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40 + @@: + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + jne @f +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" + RTL_W8 0x82,0x01 +; DEBUGF 1,"K : Set PHY Reg 0x0bh = 0x00h\n" + stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000 ; w 0x0b 15 0 0 + @@: + ; if TBI is not enabled + RTL_R8 RTL8169_REG_PHYstatus + test al,RTL8169_PHYS_TBI_Enable + jz .tbi_dis + stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG + ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged + and eax,0x0C1F + or eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax + ; enable 1000 Full Mode + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168 + ; Enable auto-negotiation and restart auto-nigotiation + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego + stdcall udelay,100 + mov ecx,10000 + ; wait for auto-negotiation process + @@: dec ecx + jz @f + stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG + stdcall udelay,100 + test eax,RTL8169_PHY_Auto_Neco_Comp + jz @b + RTL_R8 RTL8169_REG_PHYstatus + jmp @f + .tbi_dis: + stdcall udelay,100 + @@: + call rtl8169_reset + ret +endp + +;*************************************************************************** +; Function +; rt8169_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +proc rtl8169_reset + + DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring + ; Tx Desscriptor needs 256 bytes alignment + mov [rtl8169_tpc.TxDescArray],rtl8169_tx_ring + + mov [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring + ; Rx Desscriptor needs 256 bytes alignment + mov [rtl8169_tpc.RxDescArray],rtl8169_rx_ring + + call rtl8169_init_ring + call rtl8169_hw_start + ; Construct a perfect filter frame with the mac address as first match + ; and broadcast for all others + mov edi,rtl8169_txb + or al,-1 + mov ecx,192 + cld + rep stosb + + mov esi,node_addr + mov edi,rtl8169_txb + movsd + movsw + + mov eax,[pci_data] + mov [eth_status],eax + ret +endp + +;*************************************************************************** +; Function +; rtl8169_transmit +; Description +; Transmits a packet of data via the ethernet card +; d - edi - Pointer to 48 bit destination address +; t - bx - Type of packet +; s - ecx - size of packet +; p - esi - pointer to packet data +; Destroyed registers +; eax, edx, esi, edi +; +;*************************************************************************** +proc rtl8169_transmit + + DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi + + push ecx edx esi + mov eax,MAX_ETH_FRAME_SIZE + mul [rtl8169_tpc.cur_tx] + mov esi,edi + ; point to the current txb incase multiple tx_rings are used + mov edi,[rtl8169_tpc.Tx_skbuff + eax * 4] + mov eax,edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi,node_addr + movsd + movsw +; copy packet type + mov [edi],bx + add edi,2 +; copy the packet data + pop esi edx ecx + push ecx + shr ecx,2 + rep movsd + pop ecx + push ecx + and ecx,3 + rep movsb + +;!!! s += ETH_HLEN; +;!!! s &= 0x0FFF; +;!!! while (s < ETH_ZLEN) +;!!! ptxb[s++] = '\0'; + mov edi,eax + pop ecx + push eax + add ecx,ETH_HLEN + and ecx,0x0FFF + xor al,al + add edi,ecx + @@: cmp ecx,ETH_ZLEN + jae @f + stosb + inc ecx + jmp @b + @@: pop eax + + mov ebx,eax + mov eax,sizeof.rtl8169_TxDesc + mul [rtl8169_tpc.cur_tx] + add eax,[rtl8169_tpc.TxDescArray] + xchg eax,ebx + mov [ebx + rtl8169_TxDesc.buf_addr],eax + + mov eax,ecx + cmp eax,ETH_ZLEN + jae @f + mov eax,ETH_ZLEN + @@: or eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit + cmp [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 + jne @f + or eax,RTL8169_DSB_EORbit + @@: mov [ebx + rtl8169_TxDesc.status],eax + + RTL_W8 RTL8169_REG_TxPoll,0x40 ; set polling bit + + inc [rtl8169_tpc.cur_tx] + and [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 + +;!!! to = currticks() + TX_TIMEOUT; +;!!! while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */ + mov ecx,TX_TIMEOUT / 10 + @@: test [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit + jnz @f + stdcall udelay,10 + loop @b + DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n" + @@: + + ret +endp + +;*************************************************************************** +; Function +; rtl8169_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Destroyed register(s) +; eax, edx, ecx +; +;*************************************************************************** +proc rtl8169_poll + +; DEBUGF 1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8 + + mov word[eth_rx_data_len],0 + + mov eax,sizeof.rtl8169_RxDesc + mul [rtl8169_tpc.cur_rx] + add eax,[rtl8169_tpc.RxDescArray] + mov ebx,eax + +; DEBUGF 1,"K : rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status] + + test [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600 + jnz .exit + +; DEBUGF 1,"K : rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx] + + ; h/w no longer present (hotplug?) or major error, bail + RTL_R16 RTL8169_REG_IntrStatus + +; DEBUGF 1,"K : IntrStatus = 0x%x\n",ax + + cmp ax,0xFFFF + je .exit + + push eax + and ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK) + RTL_W16 RTL8169_REG_IntrStatus,ax + + mov eax,[ebx + rtl8169_RxDesc.status] + +; DEBUGF 1,"K : RxDesc.status = 0x%x\n",eax + + test eax,RTL8169_SD_RxRES + jnz .else + and eax,0x00001FFF +; jz .exit.pop + add eax,-4 + mov [eth_rx_data_len],ax + + DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax + + push eax + mov ecx,eax + shr ecx,2 + mov eax,[rtl8169_tpc.cur_rx] + mov edx,[rtl8169_tpc.RxBufferRing + eax * 4] + mov esi,edx + mov edi,Ether_buffer + cld + rep movsd + pop ecx + and ecx,3 + rep movsb + + mov eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE + cmp [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 + jne @f + or eax,RTL8169_DSB_EORbit + @@: mov [ebx + rtl8169_RxDesc.status],eax + + mov [ebx + rtl8169_RxDesc.buf_addr],edx + jmp @f + .else: + DEBUGF 1,"K : rtl8169_poll: Rx Error\n" + ; FIXME: shouldn't I reset the status on an error + @@: + inc [rtl8169_tpc.cur_rx] + and [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 + .exit.pop: + pop eax + and ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK + RTL_W16 RTL8169_REG_IntrStatus,ax + .exit: + ret +endp + +proc rtl8169_cable + ret +endp diff --git a/kernel/trunk/network/eth_drv/ethernet.inc b/kernel/trunk/network/eth_drv/ethernet.inc index a25adda205..32686464e9 100644 --- a/kernel/trunk/network/eth_drv/ethernet.inc +++ b/kernel/trunk/network/eth_drv/ethernet.inc @@ -98,6 +98,7 @@ include "drivers/3c59x.inc" include "drivers/sis900.inc" include "drivers/pcnet32.inc" ;include "drivers/mtd80x.inc" +include "drivers/rtl8169.inc" ; PCICards ; ======== @@ -143,6 +144,11 @@ dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rt dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 +dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 + dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 @@ -433,12 +439,13 @@ eth_rx: jmp .exit ; If not IP or ARP, ignore .is_ip: + DEBUGF 1,"K : eth_rx - IP packet\n" inc dword [ip_rx_count] call ether_IP_handler jmp .exit .is_arp: - + DEBUGF 1,"K : eth_rx - ARP packet\n" ; At this point, the packet is still in the Ether_buffer call arp_handler diff --git a/kernel/trunk/network/ip.inc b/kernel/trunk/network/ip.inc index 38e126ce96..6e8d3b27d0 100644 --- a/kernel/trunk/network/ip.inc +++ b/kernel/trunk/network/ip.inc @@ -158,6 +158,7 @@ local buffer_number dd ? cmp al , PROTOCOL_TCP jne .not_tcp + DEBUGF 1,"K : ip_rx - TCP packet\n" mov eax, dword[buffer_number] call tcp_rx jmp .exit @@ -165,6 +166,7 @@ local buffer_number dd ? .not_tcp: cmp al, PROTOCOL_UDP jne .not_udp + DEBUGF 1,"K : ip_rx - UDP packet\n" mov eax, dword[buffer_number] call udp_rx jmp .exit @@ -173,6 +175,7 @@ local buffer_number dd ? cmp al , PROTOCOL_ICMP jne .dump ;protocol ain't supported + DEBUGF 1,"K : ip_rx - ICMP packet\n" ;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx mov eax, dword[buffer_number] stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength