?? 3c59x.inc
字號:
test al, 100000b ; check 10Mbps AUI connector jz .coax_available lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] in eax, dx and eax, not (1111b shl 20) or eax, (0001b shl 20) ; set 10Mbps AUI connector out dx, eax xor al, al ; try 10Mbps AUI connector call e3c59x_try_loopback test al, al jz .coax_available ret.coax_available:; switch to register window 3 lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 out dx, ax; check for coaxial 10BASE-2 port lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] in ax, dx ; read media option register test al, 10000b ; check 10BASE-2 jz .set_first_available_media lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] in eax, dx and eax, not (1111b shl 20) or eax, (0011b shl 20) ; set 10BASE-2 out dx, eax mov al, 1 call e3c59x_try_loopback test al, al jz .set_first_available_media ret.set_first_available_media: jmp e3c59x_set_available_media;***************************************************************************; Function; e3c59x_wake_up; Description; set the power state to D0; Destroyed registers; eax, ebx, ecx, edx, edi, esi;;*************************************************************************** align 4e3c59x_wake_up:; wake up - we directly do it by programming PCI; check if the device is power management capable mov al, 2 mov ah, [pci_bus] mov bl, PCI_REG_STATUS mov bh, [pci_dev] push eax ebx call pci_read_reg test al, 10000b ; is there "new capabilities" linked list? pop ebx eax jz .device_awake; search for power management register mov al, 1 mov bl, PCI_REG_CAP_PTR push eax ebx call pci_read_reg mov cl, al cmp cl, 0x3f pop ebx eax jbe .device_awake; traverse the list mov al, 2.pm_loop: mov bl, cl push eax ebx call pci_read_reg cmp al, 1 je .set_pm_state test ah, ah mov cl, ah pop ebx eax jnz .pm_loop jmp .device_awake; waku up the device if necessary.set_pm_state: pop ebx eax add bl, PCI_REG_PM_CTRL push eax ebx call pci_read_reg mov cx, ax test cl, 3 pop ebx eax jz .device_awake and cl, not 11b ; set state to D0 call pci_write_reg.device_awake: ret;***************************************************************************; Function; e3c59x_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, edi, esi;;*************************************************************************** align 4e3c59x_probe: movzx ebp, word [io_addr] mov al, 2 mov ah, [pci_bus] mov bh, [pci_dev] mov bl, PCI_REG_COMMAND push ebp eax ebx call pci_read_reg mov cx, ax or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) and cl, not (1 shl PCI_BIT_MMIO) pop ebx eax call pci_write_reg; wake up the card call e3c59x_wake_up pop ebp; get chip version mov ax, [pci_data+2] mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1.chip_ver_loop: cmp ax, [e3c59x_hw_versions+ecx*4] jz .chip_ver_found dec ecx jns .chip_ver_loop xor ecx, ecx.chip_ver_found: mov [e3c59x_ver_id], cl test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM setnz [e3c59x_has_hwcksm]; set pci latency for vortex cards test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX jz .not_vortex mov cx, 11111000b ; 248 = max latency mov al, 1 mov ah, [pci_bus] mov bl, PCI_REG_LATENCY mov bh, [pci_dev] call pci_write_reg.not_vortex:; set RX/TX functions mov ax, E3C59X_EEPROM_REG_CAPABILITIES call e3c59x_read_eeprom test al, 100000b ; full bus master? setnz [e3c59x_full_bus_master] jnz .boomerang_func mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit mov dword [e3c59x_receive_function], e3c59x_vortex_poll jmp @f.boomerang_func: ; full bus master, so use boomerang functions mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit mov dword [e3c59x_receive_function], e3c59x_boomerang_poll@@:; read MAC from eeprom mov ecx, 2.mac_loop: lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx] call e3c59x_read_eeprom xchg ah, al ; htons mov [node_addr+ecx*2], ax dec ecx jns .mac_loop test byte [e3c59x_full_bus_master], 0xff jz .set_preamble; switch to register window 2 lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 out dx, ax; activate xcvr by setting some magic bits lea edx, [ebp+E3C59X_REG_RESET_OPTIONS] in ax, dx and ax, not 0x4010 movzx ebx, byte [e3c59x_ver_id] test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR jz @f or al, 0x10@@: test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR jz @f or ah, 0x40@@: out dx, ax.set_preamble:; use preamble as default mov byte [e3c59x_preamble], 1 ; enable preamble;***************************************************************************; Function; e3c59x_reset; Description; Place the chip (ie, the ethernet card) into a virgin state; Destroyed registers; eax, ebx, ecx, edx, edi, esi;;***************************************************************************e3c59x_reset:; issue global reset call e3c59x_global_reset; disable interrupts lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, (1110b shl 11) out dx, ax; enable Statistics mov ax, (10101b shl 11) out dx, ax; set indication mov ax, (1111b shl 11) or 0x6c6 out dx, ax; acknowledge (clear) every interrupt indicator mov ax, (1101b shl 11) or 0x661 out dx, ax; switch to register window 2 mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 out dx, ax; write MAC addres back into the station address registers lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO] mov esi, node_addr cld outsw add edx, 2 outsw add edx, 2 outsw add edx, 2; clear station mask xor eax, eax out dx, ax add edx, 2 out dx, ax add edx, 2 out dx, ax; switch to register window 6 lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, E3C59X_SELECT_REGISTER_WINDOW+6 out dx, ax; clear all statistics by reading lea edx, [ebp+E3C59X_REG_CARRIER_LOST] mov cl, 9.stat_clearing_loop: in al, dx inc edx dec cl jns .stat_clearing_loop in ax, dx add dx, 2 in ax, dx; switch to register window 4 lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 out dx, ax; clear BadSSD lea edx, [ebp+E3C59X_REG_BAD_SSD] in al, dx; clear extra statistics bit in NetworkDiagnostic lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC] in ax, dx or ax, 0x0040 out dx, ax; SetRxEarlyThreshold lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2) out dx, ax test byte [e3c59x_full_bus_master], 0xff jz .skip_boomerang_setting; set upRxEarlyEnable lea edx, [ebp+E3C59X_REG_DMA_CTRL] in eax, dx or eax, 0x20 out dx, eax; TxFreeThreshold lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH] mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256) out dx, al; program DnListPtr lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] xor eax, eax out dx, eax.skip_boomerang_setting:; initialization call e3c59x_rx_reset call e3c59x_tx_reset call e3c59x_set_active_port call e3c59x_rx_reset call e3c59x_tx_reset; switch to register window 5 lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 out dx, ax; program RxFilter for promiscuous operation mov ax, (10000b shl 11) lea edx, [ebp+E3C59X_REG_RX_FILTER] in al, dx or al, 1111b lea edx, [ebp+E3C59X_REG_COMMAND] out dx, ax; switch to register window 4 mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 out dx, ax; wait for linkDetect lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] mov cl, 20 ; wait for max 2s mov esi, 100 ; 100ms.link_detect_loop: call delay_ms in ax, dx test ah, 1000b ; linkDetect jnz @f dec cl jnz .link_detect_loop@@:; Indicate that we have successfully reset the card mov eax, [pci_data] mov [eth_status], eaxif defined E3C59X_DEBUG call e3c59x_debugend if ; defined E3C59X_DEBUG ret;***************************************************************************; Function; e3c59x_global_reset; Description; resets the device; Parameters:; ebp - io_addr; Return value:; Destroyed registers; ax, ecx, edx, esi;;*************************************************************************** align 4e3c59x_global_reset:; GlobalReset lea edx, [ebp+E3C59X_REG_COMMAND] xor eax, eax; or al, 0x14 out dx, ax; wait for GlobalReset to complete mov ecx, 64000.global_reset_loop: in ax, dx test ah, 10000b ; check CmdInProgress jz .finish dec ecx jnz .global_reset_loop.finish:; wait for 2 seconds for NIC to boot mov esi, 2000 ; 2000ms = 2s push ebp call delay_ms pop ebp ret;***************************************************************************; Function; e3c59x_tx_reset; Description; resets and enables transmitter engine; Parameters:; ebp - io_addr; Return value:; Destroyed registers; ax, ecx, edx;;*************************************************************************** align 4e3c59x_tx_reset:; TxReset lea edx, [ebp+E3C59X_REG_COMMAND] mov ax, (01011b shl 11) out dx, ax; wait for TxReset to complete mov ecx, 2000.tx_reset_loop: in ax, dx test ah, 10000b ; check CmdInProgress jz .tx_enable dec ecx jns .tx_reset_loop test byte [e3c59x_full_bus_master], 0xff jz .tx_enable; init last_dpd mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE.tx_enable: mov ax, (01001b shl 11) ; TxEnable out dx, ax ret
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -