(** AUTHOR: Alexey Morozov; PURPOSE: driver for the 8136 family of Realtek PCI Express Fast Ethernet (FE) controllers This driver implementation is based on the source code of the linux driver from Realtek (http://www.realtek.com.tw) r8101-1.025.00 List of supported devices: RTL8100E/RTL8101E/RTL8102E-GR/RTL8103E(L) RTL8102E(L)/RTL8101E/RTL8103T RTL8401/RTL8401P/RTL8105E RTL8402/RTL8106E/RTL8106EUS *) MODULE RTL8136; IMPORT S := SYSTEM, Kernel, Machine, PCI, Objects, Modules, Plugins, Network, NetworkMii, KernelLog; CONST Description = "RealTek 8136 PCI-E FE driver"; MaxETHFrameSize = 1514; TxBufMaxSize = 1536; (* Max size of tx buffers *) RxRingSize = 1024; (* Rx Ring of 116 buffers *) TxRingSize = 1024; (* Tx Ring of 116 buffers *) SizeOfRxTxFDHdr = 16; (* size of Rx / Tx Descriptor Header *) Promisc = FALSE; (* enable Promiscuous mode *) DebugFind = 0; DebugInit = 1; DebugConfigs = 2; DebugHWVer = 3; DebugMAC = 4; DebugStatus = 5; DebugRxRing = 6; DebugTxRing = 7; DebugReceive = 8; DebugTransmit = 9; DebugInterrupt = 10; DebugCleanup = 31; Debug = {(*DebugTransmit,DebugReceive,*)DebugFind, DebugInit, DebugTxRing, DebugCleanup}; (* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. *) SPEED_10 = 10; SPEED_100 = 100; ASPM = FALSE; (* Registers *) MAC0 = 0; (* Ethernet hardware address. *) MAC4 = 0x04; MAR0 = 8; (* Multicast filter. *) CounterAddrLow = 0x10; CounterAddrHigh = 0x14; TxDescStartAddrLow = 0x20; TxDescStartAddrHigh = 0x24; TxHDescStartAddrLow = 0x28; TxHDescStartAddrHigh = 0x2c; ERSR = 0x36; ChipCmd = 0x37; TxPoll = 0x38; IntrMask = 0x3C; IntrStatus = 0x3E; TxConfig = 0x40; RxConfig = 0x44; (* RxMissed = 0x4C; *) TCTR = 0x48; Cfg9346 = 0x50; Config0 = 0x51; Config1 = 0x52; Config2 = 0x53; Config3 = 0x54; Config4 = 0x55; Config5 = 0x56; TDFNR = 0x57; TimeIntr = 0x58; PHYAR = 0x60; CSIDR = 0x64; CSIAR = 0x68; PHYstatus = 0x6C; MACDBG = 0x6D; GPIO = 0x6E; PMCH = 0x6F; ERIDR = 0x70; ERIAR = 0x74; EPHYAR = 0x80; OCPDR = 0xB0; MACOCP = 0xB0; OCPAR = 0xB4; PHYOCP = 0xB8; DBG_reg = 0xD1; MCUCmd_reg = 0xD3; RxMaxSize = 0xDA; CPlusCmd = 0xE0; IntrMitigate = 0xE2; RxDescAddrLow = 0xE4; RxDescAddrHigh = 0xE8; MTPS = 0xEC; PHYIO = 0xF8; (* Register content *) (* InterruptStatusBits *) SYSErr = 15; PCSTimeout = 14; SWInt = 8; TxDescUnavail = 7; RxFIFOOver = 6; LinkChg = 5; RxDescUnavail = 4; TxErr = 3; TxOK = 2; RxErr = 1; RxOK = 0; (* RxStatusDesc *) RxRES = 0x00200000; RxCRC = 0x00080000; RxRUNT = 0x00100000; RxRWT = 0x00400000; (* ChipCmdBits *) StopReq = S.VAL(SET,0x80); CmdReset = S.VAL(SET,0x10); CmdRxEnb = S.VAL(SET,0x08); CmdTxEnb = S.VAL(SET,0x04); RxBufEmpty = S.VAL(SET,0x01); (* Cfg9346Bits *) Cfg9346_Lock = S.VAL(SET,0x00); Cfg9346_Unlock = S.VAL(SET,0xC0); Cfg9346_EEDO = {0}; Cfg9346_EEDI = {1}; Cfg9346_EESK = {2}; Cfg9346_EECS = {3}; Cfg9346_EEM0 = {6}; Cfg9346_EEM1 = {7}; (* rx_mode_bits *) AcceptErr = S.VAL(SET,0x20); AcceptRunt = S.VAL(SET,0x10); AcceptBroadcast = S.VAL(SET,0x08); AcceptMulticast = S.VAL(SET,0x04); AcceptMyPhys = S.VAL(SET,0x02); AcceptAllPhys = S.VAL(SET,0x01); (* Transmit Priority Polling*) HPQ = S.VAL(SET,0x80); NPQ = S.VAL(SET,0x40); FSWInt = S.VAL(SET,0x01); (* RxConfigBits *) Reserved2_shift = 13; RxCfgDMAShift = 8; RxCfg_9356SEL = {6}; (* TxConfigBits *) TxInterFrameGapShift = 24; TxDMAShift = 8; (* DMA burst value (0-7) is shift this many bits *) TxMACLoopBack = {17}; (* MAC loopback *) (* Config1 register *) LEDS1 = {7}; LEDS0 = {6}; Speed_down = {4}; MEMMAP = {3}; IOMAP = {2}; VPD = {1}; PMEnable = {0}; (* Power Management Enable *) (* Config2 register *) PMSTS_En = {5}; (* Config3 register *) MagicPacket = {5}; (* Wake up when receives a Magic Packet *) LinkUp = {4}; (* Wake up when the cable connection is re-established *) (* Config5 register *) BWF = {6}; (* Accept Broadcast wakeup frame *) MWF = {5}; (* Accept Multicast wakeup frame *) UWF = {4}; (* Accept Unicast wakeup frame *) LanWake = {1}; (* LanWake enable/disable *) PMEStatus = {0}; (* PME status can be reset by PCI RST# *) ECRCEN = {3}; Jumbo_En = {2}; RDY_TO_L23 = {1}; Beacon_en = {0}; (* Config4 register *) LANWake = {1}; (* CPlusCmd *) EnableBist = {15}; Macdbgo_oe = {14}; Normal_mode = {13}; Force_halfdup = {12}; Force_rxflow_en = {11}; Force_txflow_en = {10}; Cxpl_dbg_sel = {9}; ASF = {8}; PktCntrDisable = {7}; RxVlan = {6}; RxChkSum = {5}; PCIDAC = {4}; Macdbgo_sel = 0x001C; INTT_0 = 0x0000; INTT_1 = 0x0001; INTT_2 = 0x0002; INTT_3 = 0x0003; (* PHYstatus *) PowerSaveStatus = S.VAL(SET,0x80); TxFlowCtrl = S.VAL(SET,0x40); RxFlowCtrl = S.VAL(SET,0x20); _100bps = S.VAL(SET,0x08); _10bps = S.VAL(SET,0x04); LinkStatus = S.VAL(SET,0x02); FullDup = S.VAL(SET,0x01); (* DumpCounterCommand *) CounterDump = 0x8; (* PHY access *) PHYAR_Flag = S.VAL(SET,0x80000000); PHYAR_Write = S.VAL(SET,0x80000000); PHYAR_Read = S.VAL(SET,0x00000000); PHYAR_Reg_Mask = S.VAL(SET,0x1f); PHYAR_Reg_shift = 16; PHYAR_Data_Mask = S.VAL(SET,0xffff); (* PHY IO access *) PHYIO_Flag = S.VAL(SET,0x80000000); PHYIO_Write = S.VAL(SET,0x80000000); PHYIO_Read = S.VAL(SET,0x00000000); PHYIO_Reg_Mask = S.VAL(SET,0x1f); PHYIO_Reg_shift = 16; PHYIO_Data_Mask = S.VAL(SET,0xffff); (* EPHY access *) EPHYAR_Flag = S.VAL(SET,0x80000000); EPHYAR_Write = S.VAL(SET,0x80000000); EPHYAR_Read = S.VAL(SET,0x00000000); EPHYAR_Reg_Mask = S.VAL(SET,0x1f); EPHYAR_Reg_shift = 16; EPHYAR_Data_Mask = S.VAL(SET,0xffff); (* CSI access *) CSIAR_Flag = 0x80000000; CSIAR_Write = 0x80000000; CSIAR_Read = 0x00000000; CSIAR_ByteEn = 0x0f; CSIAR_ByteEn_shift = 12; CSIAR_Addr_Mask = 0x0fff; (* ERI access *) ERIAR_Flag = S.VAL(SET,0x80000000); ERIAR_Write = S.VAL(SET,0x80000000); ERIAR_Read = S.VAL(SET,0x00000000); ERIAR_Addr_Align = 4; (* ERI access register address must be 4 byte alignment *) ERIAR_ExGMAC = 0; ERIAR_MSIX = 1; ERIAR_ASF = 2; ERIAR_Type_shift = 16; ERIAR_ByteEn = 0x0f; ERIAR_ByteEn_shift = 12; (* OCP GPHY access *) OCPDR_Write = 0x80000000; OCPDR_Read = 0x00000000; OCPDR_Reg_Mask = 0xFF; OCPDR_Data_Mask = 0xFFFF; OCPDR_GPHY_Reg_shift = 16; OCPAR_Flag = 0x80000000; OCPAR_GPHY_Write = 0x8000F060; OCPAR_GPHY_Read = 0x0000F060; OCPR_Write = 0x80000000; OCPR_Read = 0x00000000; OCPR_Addr_Reg_shift = 16; OCPR_Flag = 0x80000000; OCP_STD_PHY_BASE_PAGE = 0x0A40; (* MCU Command *) Now_is_oob = {7}; Txfifo_empty = {5}; Rxfifo_empty = {4}; (* GPIO *) GPIO_en = {0}; (* Device configuration method *) CFG_METHOD_1 = 0; CFG_METHOD_2 = 1; CFG_METHOD_3 = 2; CFG_METHOD_4 = 3; CFG_METHOD_5 = 4; CFG_METHOD_6 = 5; CFG_METHOD_7 = 6; CFG_METHOD_8 = 7; CFG_METHOD_9 = 8; CFG_METHOD_10 = 9; CFG_METHOD_11 = 11; CFG_METHOD_12 = 12; CFG_METHOD_13 = 13; CFG_METHOD_14 = 14; CFG_METHOD_15 = 15; CFG_METHOD_16 = 16; CFG_METHOD_17 = 17; CFG_METHOD_MAX = 18; HwCfgMethods = [CFG_METHOD_1,CFG_METHOD_2,CFG_METHOD_3,CFG_METHOD_4,CFG_METHOD_5,CFG_METHOD_6,CFG_METHOD_7,CFG_METHOD_8,CFG_METHOD_9,CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17]; RxConfigMask = [0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880,0xff7e1880]; Reserved2_data = 7; RX_DMA_BURST = 6; (* Maximum PCI burst, '6' is 1024 *) TX_DMA_BURST = 6; (* Maximum PCI burst, '6' is 1024 *) Reserved1_data = S.VAL(SET,0x3F); RxPacketMaxSize = 0x3FE8; (* 16K - 1 - ETH_HLEN - VLAN - CRC... *) InterFrameGap = 0x03; (* 3 means InterFrameGap = the shortest one *) DSM_MAC_INIT = 1; DSM_NIC_GOTO_D3 = 2; DSM_IF_DOWN = 3; DSM_NIC_RESUME_D3 = 4; DSM_IF_UP = 5; VAR installed: LONGINT; (* number of installed devices *) TYPE (* base Rx/Tx descriptor, as described in RTL8169 specs *) RxTxDescriptor = RECORD flags: SET; vLanTag: LONGINT; bufAdrLo, bufAdrHi: LONGINT; END; (* buffer for transmission *) TxBuffer = POINTER TO RECORD data: ARRAY TxBufMaxSize OF CHAR; next: TxBuffer; END; (* wrapper for Network.Buffer to be able to form rings *) RxBuffer = POINTER TO RECORD buf: Network.Buffer; next: RxBuffer; END; (* Statistics counters as specified by Realtek *) TallyCounters = RECORD txPackets: HUGEINT; rxPacktes: HUGEINT; txErrors: HUGEINT; rxErrors: LONGINT; rxMissed: INTEGER; alignErrors: INTEGER; txOneCollision: LONGINT; txMultiCollision: LONGINT; rxUnicast: HUGEINT; rxBroadcast: HUGEINT; rxMulticast: LONGINT; txAborted: INTEGER; txUnderrun: INTEGER; END; (* LinkDevice: interface to Bluebottle *) LinkDevice = OBJECT (Network.LinkDevice) VAR ctrl: Controller; PROCEDURE Linked*(): LONGINT; BEGIN RETURN ctrl.linkStatus; END Linked; PROCEDURE DoSend*(dst: Network.LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT); BEGIN ctrl.SendFrame(dst, type, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen); END DoSend; PROCEDURE Finalize(connected: BOOLEAN); BEGIN ctrl.Finalize; Finalize^(connected); END Finalize; END LinkDevice; (* Controller: interface to the RTL8169 hardware *) Controller = OBJECT VAR next: Controller; (* next controller in list *) base: ADDRESS; irq: LONGINT; dev: LinkDevice; rdsBuf: ARRAY RxRingSize*SIZEOF(RxTxDescriptor)+255 OF CHAR; tdsBuf: ARRAY TxRingSize*SIZEOF(RxTxDescriptor)+255 OF CHAR; rds: ARRAY RxRingSize OF POINTER{UNSAFE, UNTRACED} TO RxTxDescriptor; tds: ARRAY TxRingSize OF POINTER{UNSAFE, UNTRACED} TO RxTxDescriptor; curRD, curTD: LONGINT; firstRD, firstTD: LONGINT; lastRD, lastTD: LONGINT; (*rxBuffer, rxLast: TxBuffer;*) rxBuffer, rxLast: RxBuffer; txBuffer, txLast: TxBuffer; nofFreeTx: LONGINT; (* number of free tx descriptors *) nRxOverflow: HUGEINT; nTxOverflow: HUGEINT; nRxFrames, nTxFrames: LONGINT; nRxErrorFrames: LONGINT; nTxErrorFrames: LONGINT; linkStatus: LONGINT; pciBus, pciDev, pciFct: LONGINT; hwCfgMethod, chipsetInd: LONGINT; hwIcVerUnknown: BOOLEAN; phy_auto_nego_reg: SET; cp_cmd: SET; bios_setting: SET; use_timer_interrrupt: BOOLEAN; eee_enable: BOOLEAN; intr_mask: SET; rx_buf_sz: LONGINT; autoneg: BOOLEAN; speed: LONGINT; duplexFull: BOOLEAN; wol_enabled: BOOLEAN; notWrRamCodeToMicroP: BOOLEAN; hwHasWrRamCodeToMicroP: BOOLEAN; notWrMcuPatchCode: BOOLEAN; txDescStartAddr, rxDescStartAddr: ADDRESS; counters(*{ALIGNED=64}*): TallyCounters; PROCEDURE &InitController( dev: LinkDevice; base: ADDRESS; irq: LONGINT; pciBus, pciDev, pciFct: LONGINT; hwCfgMethod: LONGINT; chipsetInd: LONGINT; hwIcVerUnknown: BOOLEAN); VAR res, i: LONGINT; s: SET; BEGIN (* update list of installed controllers, insert at head *) SELF.next := installedControllers; installedControllers := SELF; SELF.base := base; SELF.dev := dev; SELF.irq := irq; SELF.pciDev := pciDev; SELF.pciBus := pciBus; SELF.pciFct := pciFct; SELF.hwCfgMethod := hwCfgMethod; SELF.chipsetInd := chipsetInd; SELF.hwIcVerUnknown := hwIcVerUnknown; dev.ctrl := SELF; nRxOverflow := 0; nTxOverflow := 0; nRxFrames := 0; nTxFrames := 0; nRxErrorFrames := 0; nTxErrorFrames := 0; (* tell the system that the nic calculates the checksums for tcp, udp and ip packets *) dev.calcChecksum := {Network.ChecksumIP, Network.ChecksumTCP, Network.ChecksumUDP}; (* set ethernet broadcast address: FF-FF-FF-FF-FF-FF *) FOR i := 0 TO 5 DO dev.broadcast[i] := 0FFX END; (* make sure PIO and MMIO are enabled*) s := S.VAL(SET,Read8(52H)); IF ~ (2 IN s) THEN KernelLog.String("I/O Mapping is disabled!"); HALT(1000); END; IF ~ (3 IN s) THEN KernelLog.String("MMIO is disabled!"); HALT(1000); END; (* install interrupt handler *) IF (irq >= 1) & (irq <= 15) THEN Objects.InstallHandler(SELF.HandleInterrupt, Machine.IRQ0 + irq) END; (* *) init_one; open; (* enable transmitter and receiver *) Write8(ChipCmd, CmdTxEnb+CmdRxEnb); (* Enable all known interrupts by setting the interrupt mask. *) Write16(IntrMask, intr_mask); (* *) UpdateLinkStatus; (* register device with Network *) Network.registry.Add(dev, res); ASSERT(res = Plugins.Ok); INC(installed); IF DebugConfigs IN Debug THEN DebugConfig; END; END InitController; PROCEDURE hw_mac_mcu_config; BEGIN IF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) END; END hw_mac_mcu_config; PROCEDURE hw_init; BEGIN CASE hwCfgMethod OF |CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: Write8(Cfg9346, Cfg9346_Unlock); Write8(Config5, Read8(Config5) - {0}); Write8(Config2, Read8(Config2) - {7}); Write8(Cfg9346, Cfg9346_Lock); Write8(0xF1, Read8(0xF1) - {7}); ELSE END; IF hwCfgMethod = CFG_METHOD_17 THEN Write8(Cfg9346, Cfg9346_Unlock); Write8(Config5, Read8(Config5) - {0}); Write8(Config2, Read8(Config2) - {7}); Write8(Cfg9346, Cfg9346_Lock); Write8(0xF1, Read8(0xF1) - {7}); END; IF hwCfgMethod = CFG_METHOD_10 THEN Write8(0xF3, Read8(0xF3) + {2}); END; hw_mac_mcu_config; (*disable ocp phy power saving*) IF hwCfgMethod = CFG_METHOD_17 THEN mdio_write1(0x1F, 0x0C41); mdio_write1(0x13, 0x0000); mdio_write1(0x13, 0x0500); mdio_write1(0x1F, 0x0000); END; END hw_init; PROCEDURE irq_mask_and_ack; BEGIN Write16(IntrMask, {}); Write16(IntrStatus, Read16(IntrStatus)); END irq_mask_and_ack; PROCEDURE hw_reset; BEGIN (* Disable interrupts *) irq_mask_and_ack; nic_reset; END hw_reset; PROCEDURE get_mac_address; VAR i: LONGINT; s: SET; BEGIN (* MAC address is in registers 00H - 05H *) IF DebugMAC IN Debug THEN KernelLog.String("MAC address is: "); END; FOR i := 0 TO 5 DO s := Read8(i); S.PUT8(ADDRESSOF(dev.local[i]), s); IF DebugMAC IN Debug THEN IF i > 0 THEN KernelLog.String("-"); END; KernelLog.Hex(ORD(dev.local[i]), -2); END; END; IF DebugMAC IN Debug THEN KernelLog.Ln; END; dev.adrSize := 6; END get_mac_address; PROCEDURE init_one; BEGIN cp_cmd := cp_cmd + Read16(CPlusCmd); init_software_variable; exit_oob; hw_init; hw_reset; get_mac_address; speed := SPEED_100; autoneg := TRUE; duplexFull := TRUE; END init_one; PROCEDURE set_rxbufsize; BEGIN CASE hwCfgMethod OF |CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: rx_buf_sz := 0x05F3; ELSE rx_buf_sz := 0x05EF; END; END set_rxbufsize; PROCEDURE tally_counter_clear; BEGIN IF (hwCfgMethod = CFG_METHOD_1) OR (hwCfgMethod = CFG_METHOD_2) OR (hwCfgMethod = CFG_METHOD_3) THEN RETURN; END; (*IF tally_paddr = 0 THEN RETURN; END; Write32(CounterAddrHigh, (u64)tally_paddr >> 32); Write32(CounterAddrLow, (u64)tally_paddr & (DMA_BIT_MASK(32) | BIT_0));*) END tally_counter_clear; PROCEDURE phy_power_up; VAR csi_tmp: SET; BEGIN mdio_write1(0x1f, 0x0000); CASE hwCfgMethod OF |CFG_METHOD_17: csi_tmp := eri_read(0x1AB, 1, ERIAR_ExGMAC); csi_tmp := csi_tmp + {2..7}; eri_write(0x1AB, 1, csi_tmp, ERIAR_ExGMAC); ELSE END; mdio_write(NetworkMii.BMCR, NetworkMii.BMCR_AutoNegotiationEnable); END phy_power_up; PROCEDURE powerup_pll; BEGIN CASE hwCfgMethod OF |CFG_METHOD_6,CFG_METHOD_9: Write8(PMCH, Read8(PMCH) + {7}); Write8(DBG_reg, Read8(DBG_reg) - {3}); |CFG_METHOD_7,CFG_METHOD_8,CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: Write8(PMCH, Read8(PMCH) + {7}); ELSE END; phy_power_up; END powerup_pll; PROCEDURE ephy_write(regAddr: LONGINT; value: SET); VAR i: LONGINT; BEGIN Write32(EPHYAR,EPHYAR_Write + S.VAL(SET,LSH(S.VAL(LONGINT,S.VAL(SET,regAddr) * EPHYAR_Reg_Mask),EPHYAR_Reg_shift)) + (value * EPHYAR_Data_Mask)); (* Check if the RTL8101 has completed EPHY write *) i := 0; WHILE (i < 10) & (Read32(EPHYAR) * EPHYAR_Flag # {}) DO Delay(1); INC(i); END; ASSERT(i < 10); Delay(1); END ephy_write; PROCEDURE ephy_write1(regAddr: LONGINT; value: LONGINT); BEGIN ephy_write(regAddr,S.VAL(SET,value)); END ephy_write1; PROCEDURE ephy_read(regAddr: LONGINT): SET; VAR i: LONGINT; BEGIN Write32(EPHYAR,EPHYAR_Read + S.VAL(SET,LSH(S.VAL(LONGINT,S.VAL(SET,regAddr) * EPHYAR_Reg_Mask),EPHYAR_Reg_shift))); (* Check if the RTL8101 has completed EPHY read *) i := 0; WHILE (i < 10) & (Read32(EPHYAR) * EPHYAR_Flag = {}) DO Delay(1); INC(i); END; ASSERT(i < 10); RETURN Read32(EPHYAR) * EPHYAR_Data_Mask; END ephy_read; PROCEDURE hw_ephy_config; VAR s: SET; BEGIN IF hwCfgMethod = CFG_METHOD_4 THEN ephy_write1(0x03, 0xc2f9); ELSIF hwCfgMethod = CFG_METHOD_5 THEN ephy_write1(0x01, 0x6FE5); ephy_write1(0x03, 0xD7D9); ELSIF hwCfgMethod = CFG_METHOD_6 THEN ephy_write1(0x06, 0xAF35); ELSIF hwCfgMethod = CFG_METHOD_7 THEN ephy_write1(0x19, 0xEC90); ephy_write1(0x01, 0x6FE5); ephy_write1(0x03, 0x05D9); ephy_write1(0x06, 0xAF35); ELSIF hwCfgMethod = CFG_METHOD_8 THEN ephy_write1(0x01, 0x6FE5); ephy_write1(0x03, 0x05D9); ephy_write1(0x06, 0xAF35); ephy_write1(0x19, 0xECFA); ELSIF hwCfgMethod = CFG_METHOD_9 THEN ephy_write1(0x01, 0x6FE5); ephy_write1(0x03, 0x0599); ephy_write1(0x06, 0xAF25); ephy_write1(0x07, 0x8E68); ELSIF hwCfgMethod = CFG_METHOD_10 THEN s := ephy_read(0x00) - S.VAL(SET,0x0200); s := s + S.VAL(SET,0x0100); ephy_write(0x00, s); s := ephy_read(0x00); s := s + S.VAL(SET,0x0004); ephy_write(0x00, s); s := ephy_read(0x06) - S.VAL(SET,0x0002); s := s + S.VAL(SET,0x0001); ephy_write(0x06, s); s := ephy_read(0x06); s := s + S.VAL(SET,0x0030); ephy_write(0x06, s); s := ephy_read(0x07); s := s + S.VAL(SET,0x2000); ephy_write(0x07, s); s := ephy_read(0x00); s := s + S.VAL(SET,0x0020); ephy_write(0x00, s); s := ephy_read(0x03) - S.VAL(SET,0x5800); s := s + S.VAL(SET,0x2000); ephy_write(0x03, s); s := ephy_read(0x03); s := s + S.VAL(SET,0x0001); ephy_write(0x03, s); s := ephy_read(0x01) - S.VAL(SET,0x0800); s := s + S.VAL(SET,0x1000); ephy_write(0x01, s); s := ephy_read(0x07); s := s + S.VAL(SET,0x4000); ephy_write(0x07, s); s := ephy_read(0x1E); s := s + S.VAL(SET,0x2000); ephy_write(0x1E, s); ephy_write1(0x19, 0xFE6C); s := ephy_read(0x0A); s := s + S.VAL(SET,0x0040); ephy_write(0x0A, s); ELSIF (hwCfgMethod = CFG_METHOD_11) OR (hwCfgMethod = CFG_METHOD_12) OR (hwCfgMethod = CFG_METHOD_13) THEN s := ephy_read(0x07); s := s + S.VAL(SET,0x4000); ephy_write(0x07, s); s := ephy_read(0x19); s := s +S.VAL(SET,0x0200); ephy_write(0x19, s); s := ephy_read(0x19); s := s + S.VAL(SET,0x0020); ephy_write(0x19, s); s := ephy_read(0x1E); s := s + S.VAL(SET,0x2000); ephy_write(0x1E, s); s := ephy_read(0x03); s := s + S.VAL(SET,0x0001); ephy_write(0x03, s); s := ephy_read(0x19); s := s + S.VAL(SET,0x0100); ephy_write(0x19, s); s := ephy_read(0x19); s := s + S.VAL(SET,0x0004); ephy_write(0x19, s); s := ephy_read(0x0A); s := s + S.VAL(SET,0x0020); ephy_write(0x0A, s); IF hwCfgMethod = CFG_METHOD_11 THEN Write8(Config5, Read8(Config5) - {0}); ELSIF (hwCfgMethod = CFG_METHOD_12) OR (hwCfgMethod = CFG_METHOD_13) THEN s := ephy_read(0x1E); s := s + S.VAL(SET,0x8000); ephy_write(0x1E, s); END; ELSIF hwCfgMethod = CFG_METHOD_14 THEN ephy_write1(0x19, 0xff64); ELSIF hwCfgMethod = CFG_METHOD_17 THEN s := ephy_read(0x00); s := s - {3}; ephy_write(0x00, s); s := ephy_read(0x0C); s := s - {4..13}; s := s + {11,15}; ephy_write(0x0C, s); ephy_write1(0x19, 0x7C00); ephy_write1(0x1E, 0x20EB); ephy_write1(0x0D, 0x1666); ephy_write1(0x00, 0x10A3); ephy_write1(0x06, 0xF050); END; END hw_ephy_config; PROCEDURE desc_addr_fill; BEGIN Write32(TxDescStartAddrLow, S.VAL(SET,txDescStartAddr)); Write32(TxDescStartAddrHigh, {}); Write32(RxDescAddrLow, S.VAL(SET,rxDescStartAddr)); Write32(RxDescAddrHigh, {}); END desc_addr_fill; PROCEDURE disable_rxdvgate; BEGIN IF hwCfgMethod = CFG_METHOD_17 THEN Write8(0xF2, Read8(0xF2) - {3}); Delay(2); END; END disable_rxdvgate; PROCEDURE dsm(dev_state: LONGINT); BEGIN CASE dev_state OF |DSM_MAC_INIT: IF (hwCfgMethod = CFG_METHOD_4) OR (hwCfgMethod = CFG_METHOD_5) OR (hwCfgMethod = CFG_METHOD_6) THEN IF Read8(MACDBG) * S.VAL(SET,0x80) # {} THEN mdio_write1(0x1f, 0x0000); mdio_write(0x11, mdio_read(0x11) - {12}); Write8(GPIO, Read8(GPIO) + GPIO_en); ELSE Write8(GPIO, Read8(GPIO) - GPIO_en); END; END; |DSM_NIC_GOTO_D3,DSM_IF_DOWN: IF Read8(MACDBG) * S.VAL(SET,0x80) # {} THEN IF (hwCfgMethod = CFG_METHOD_4) OR (hwCfgMethod = CFG_METHOD_5) THEN Write8(GPIO, Read8(GPIO) + GPIO_en); mdio_write(0x11, mdio_read(0x11) + {12}); ELSIF hwCfgMethod = CFG_METHOD_6 THEN Write8(GPIO, Read8(GPIO) - GPIO_en); END; END; |DSM_NIC_RESUME_D3,DSM_IF_UP: IF Read8(MACDBG) * S.VAL(SET,0x80) # {} THEN IF (hwCfgMethod = CFG_METHOD_4) OR (hwCfgMethod = CFG_METHOD_5) THEN Write8(GPIO, Read8(GPIO) -GPIO_en); ELSIF hwCfgMethod = CFG_METHOD_6 THEN Write8(GPIO, Read8(GPIO) + GPIO_en); END; END; ELSE END; END dsm; PROCEDURE hw_set_rx_packet_filter; VAR s, rx_mode: SET; BEGIN rx_mode := AcceptBroadcast + AcceptMulticast + AcceptMyPhys; s := Read32(RxConfig) * S.VAL(SET,RxConfigMask[chipsetInd]); s := s + rx_mode + S.VAL(SET,LSH(Reserved2_data,Reserved2_shift)) + S.VAL(SET,LSH(RX_DMA_BURST,RxCfgDMAShift)); Write32(RxConfig, s); Write32(MAR0 + 0, S.VAL(SET,0xFFFFFFFF)); Write32(MAR0 + 4, S.VAL(SET,0xFFFFFFFF)); END hw_set_rx_packet_filter; PROCEDURE hw_start; VAR options1, options2, s: SET; i: LONGINT; BEGIN Write32(RxConfig, S.VAL(SET,LSH(RX_DMA_BURST,RxCfgDMAShift))); hw_reset; Write8(Cfg9346,Cfg9346_Unlock); CASE hwCfgMethod OF |CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: Write8(0xF1, Read8(0xF1) - {7}); Write8(Config2, Read8(Config2) - {7}); Write8(Config5, Read8(Config5) - {0}); ELSE END; Write8(MTPS, Reserved1_data); (* Set DMA burst size and Interframe Gap Time *) Write32(TxConfig, S.VAL(SET,LSH(TX_DMA_BURST,TxDMAShift)) + S.VAL(SET,LSH(InterFrameGap,TxInterFrameGapShift))); cp_cmd := cp_cmd * S.VAL(SET,0x2063); Write16(IntrMitigate, {}); (*tally_counter_addr_fill;*) desc_addr_fill; IF hwCfgMethod = CFG_METHOD_4 THEN HALT(100); (*! Not implemented *) (*set_offset70F(0x17); set_offset79(0x50); pci_read_config_byte(pdev, 0x81, &link_control); IF link_control = {0} THEN pci_write_config_byte(pdev, 0x81, 0); Write8(DBG_reg, 0x98); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config4, Read8(Config4) | BIT_2); pci_write_config_byte(pdev, 0x81, 1); END; Write8(Config1, 0x0f); Write8(Config3, Read8(Config3) & ~Beacon_en);*) ELSIF hwCfgMethod = CFG_METHOD_5 THEN HALT(100); (*! Not implemented *) (*pci_read_config_byte(pdev, 0x81, &link_control); IF link_control = {0} THEN pci_write_config_byte(pdev, 0x81, 0); Write8(DBG_reg, 0x98); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config4, Read8(Config4) | BIT_2); pci_write_config_byte(pdev, 0x81, 1); END; set_offset79(0x50); Write8(Config1, 0x0f); Write8(Config3, Read8(Config3) & ~Beacon_en);*) ELSIF hwCfgMethod = CFG_METHOD_6 THEN HALT(100); (*! Not implemented *) (*pci_read_config_byte(pdev, 0x81, &link_control); IF link_control = {0} THEN pci_write_config_byte(pdev, 0x81, 0); Write8(DBG_reg, 0x98); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config4, Read8(Config4) | BIT_2); pci_write_config_byte(pdev, 0x81, 1); END; set_offset79(0x50); (* Write8(Config1, 0xDF); *) Write8(0xF4, 0x01); Write8(Config3, Read8(Config3) & ~Beacon_en);*) ELSIF hwCfgMethod = CFG_METHOD_7 THEN HALT(100); (*! Not implemented *) (*pci_read_config_byte(pdev, 0x81, &link_control); IF link_control = {0} THEN pci_write_config_byte(pdev, 0x81, 0); Write8(DBG_reg, 0x98); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config4, Read8(Config4) | BIT_2); pci_write_config_byte(pdev, 0x81, 1); END; set_offset79(0x50); (* Write8(Config1, (Read8(Config1)&0xC0)|0x1F);*) Write8(0xF4, 0x01); Write8(Config3, Read8(Config3) & ~Beacon_en); Write8(0xF5, Read8(0xF5) | BIT_2);*) ELSIF hwCfgMethod = CFG_METHOD_8 THEN HALT(100); (*! Not implemented *) (*pci_read_config_byte(pdev, 0x81, &link_control); IF link_control = {0} THEN pci_write_config_byte(pdev, 0x81, 0); Write8(DBG_reg, 0x98); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config4, Read8(Config4) | BIT_2); Write8(0xF4, Read8(0xF4) | BIT_3); Write8(0xF5, Read8(0xF5) | BIT_2); pci_write_config_byte(pdev, 0x81, 1); IF ephy_read(0x10) = S.VAL(SET,0x0008) THEN ephy_write1(0x10, 0x000C); END; END; pci_read_config_byte(pdev, 0x80, &link_control); IF link_control * S.VAL(SET,3) # {} THEN ephy_write(0x02, 0x011F); END; set_offset79(0x50); (* Write8(Config1, (Read8(Config1)&0xC0)|0x1F); *) Write8(0xF4, Read8(0xF4) | BIT_0); Write8(Config3, Read8(Config3) & ~Beacon_en);*) ELSIF hwCfgMethod = CFG_METHOD_9 THEN HALT(100); (*! Not implemented *) (*pci_read_config_byte(pdev, 0x81, &link_control); IF link_control = {0} THEN pci_write_config_byte(pdev, 0x81, 0); Write8(DBG_reg, 0x98); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config4, Read8(Config4) | BIT_2); pci_write_config_byte(pdev, 0x81, 1); END; set_offset79(0x50); (* Write8(Config1, 0xDF);*) Write8(0xF4, 0x01); Write8(Config3, Read8(Config3) & ~Beacon_en);*) ELSIF hwCfgMethod = CFG_METHOD_10 THEN HALT(100); (*! Not implemented *) (*set_offset70F(0x27); set_offset79(0x50); (* tx checksum offload enable *) dev->features |= NETIF_F_IP_CSUM; Write8(0xF3, Read8(0xF3) | BIT_5); Write8(0xF3, Read8(0xF3) & ~BIT_5); Write8(0xD0, Read8(0xD0) | BIT_7 | BIT_6); Write8(0xF1, Read8(0xF1) | BIT_6 | BIT_5 | BIT_4 | BIT_2 | BIT_1); IF ASPM THEN Write8(0xF1, Read8(0xF1) | BIT_7); END; Write8(Config5, (Read8(Config5)&~0x08) | BIT_0); Write8(Config2, Read8(Config2) | BIT_7); Write8(Config3, Read8(Config3) & ~Beacon_en);*) ELSIF (hwCfgMethod = CFG_METHOD_11) OR (hwCfgMethod = CFG_METHOD_12) OR (hwCfgMethod = CFG_METHOD_13) THEN cp_cmd := cp_cmd * S.VAL(SET,0x2063); i := PCI.ReadConfigByte(pciBus,pciDev,pciFct,0x80,S.VAL(LONGINT,s)); ASSERT(i = PCI.Done); TRACE(pciBus,pciDev,pciFct,S.VAL(ADDRESS,s)); IF s * S.VAL(SET,0x03) # {} THEN Write8(Config5, Read8(Config5) + {0}); Write8(0xF2, Read8(0xF2) + {7}); IF ASPM THEN Write8(0xF1, Read8(0xF1) + {7}); END; Write8(Config2, Read8(Config2) + {7}); END; Write8(0xF1, Read8(0xF1) + {3,5}); Write8(0xF2, Read8(0xF2) - {0}); Write8(0xD3, Read8(0xD3) + {2,3}); Write8(0xD0, Read8(0xD0) + {6}); Write16(0xE0, Read16(0xE0) - S.VAL(SET,0xDF9C)); IF hwCfgMethod = CFG_METHOD_11 THEN Write8(Config5, Read8(Config5) - {0}); END; ELSIF hwCfgMethod = CFG_METHOD_14 THEN HALT(100); (*! Not implemented *) (*set_offset70F(0x27); set_offset79(0x50); eri_write(0xC8, 4, 0x00000002, ERIAR_ExGMAC); eri_write(0xE8, 4, 0x00000006, ERIAR_ExGMAC); Write32(TxConfig, RTL_R32(TxConfig) | BIT_7); Write8(0xD3, Read8(0xD3) & ~BIT_7); csi_tmp = rtl8101_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); csi_tmp &= ~BIT_0; eri_write(0xDC, 1, csi_tmp, ERIAR_ExGMAC); csi_tmp |= BIT_0; eri_write(0xDC, 1, csi_tmp, ERIAR_ExGMAC); ephy_write(0x19, 0xff64); Write8(Config5, Read8(Config5) | BIT_0); Write8(Config2, Read8(Config2) | BIT_7); eri_write(0xC0, 2, 0x00000000, ERIAR_ExGMAC); eri_write(0xB8, 2, 0x00000000, ERIAR_ExGMAC); eri_write(0xD5, 1, 0x0000000E, ERIAR_ExGMAC);*) ELSIF (hwCfgMethod = CFG_METHOD_15) OR (hwCfgMethod = CFG_METHOD_16) THEN HALT(100); (*! Not implemented *) (*u8 pci_config; tp->cp_cmd &= 0x2063; (* tx checksum offload enable *) dev->features |= NETIF_F_IP_CSUM; pci_read_config_byte(pdev, 0x80, &pci_config); IF pci_config * S.VAL(SET,0x03) THEN Write8(Config5, Read8(Config5) | BIT_0); Write8(0xF2, Read8(0xF2) | BIT_7); IF ASPM THEN Write8(0xF1, Read8(0xF1) | BIT_7); END; Write8(Config2, Read8(Config2) | BIT_7); END; Write8(0xF1, Read8(0xF1) | BIT_5 | BIT_3); Write8(0xF2, Read8(0xF2) & ~BIT_0); Write8(0xD3, Read8(0xD3) | BIT_3 | BIT_2); Write8(0xD0, Read8(0xD0) & ~BIT_6); Write16(0xE0, RTL_R16(0xE0) & ~0xDF9C);*) ELSIF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) (*set_offset70F(0x17); set_offset79(0x50); eri_write(0xC8, 4, 0x00080002, ERIAR_ExGMAC); eri_write(0xCC, 1, 0x38, ERIAR_ExGMAC); eri_write(0xD0, 1, 0x48, ERIAR_ExGMAC); eri_write(0xE8, 4, 0x00100006, ERIAR_ExGMAC); Write32(TxConfig, RTL_R32(TxConfig) | BIT_7); csi_tmp = rtl8101_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); csi_tmp &= ~BIT_0; eri_write(ioaddr, 0xDC, 1, csi_tmp, ERIAR_ExGMAC); csi_tmp |= BIT_0; eri_write(ioaddr, 0xDC, 1, csi_tmp, ERIAR_ExGMAC); Write8(Config3, Read8(Config3) & ~Beacon_en); tp->cp_cmd = RTL_R16(CPlusCmd) & ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel); Write8(0x1B, Read8(0x1B) & ~0x07); Write8(TDFNR, 0x4); IF ASPM THEN Write8(0xF1, Read8(0xF1) | BIT_7); END; (* tx checksum offload enable *) dev->features |= NETIF_F_IP_CSUM; Write8(0xD0, Read8(0xD0) | BIT_6); Write8(0xF2, Read8(0xF2) | BIT_6); Write8(0xD0, Read8(0xD0) | BIT_7); eri_write(0xC0, 2, 0x0000, ERIAR_ExGMAC); eri_write(0xB8, 4, 0x00000000, ERIAR_ExGMAC); eri_write(0x5F0, 2, 0x4F87, ERIAR_ExGMAC); csi_tmp = rtl8101_eri_read(ioaddr, 0xD4, 4, ERIAR_ExGMAC); csi_tmp |= ( BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12 ); eri_write(ioaddr, 0xD4, 4, csi_tmp, ERIAR_ExGMAC); mac_ocp_write(0xC140, 0xFFFF); csi_tmp = rtl8101_eri_read(ioaddr, 0x1B0, 4, ERIAR_ExGMAC); csi_tmp &= ~BIT_12; eri_write(ioaddr, 0x1B0, 4, csi_tmp, ERIAR_ExGMAC); csi_tmp = rtl8101_eri_read(ioaddr, 0x2FC, 1, ERIAR_ExGMAC); csi_tmp &= ~(BIT_0 | BIT_1 | BIT_2); csi_tmp |= BIT_0; eri_write(ioaddr, 0x2FC, 1, csi_tmp, ERIAR_ExGMAC); csi_tmp = rtl8101_eri_read(ioaddr, 0x1D0, 1, ERIAR_ExGMAC); csi_tmp |= BIT_1; eri_write(ioaddr, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC);*) END; (*IF (hwCfgMethod = CFG_METHOD_1) OR (hwCfgMethod = CFG_METHOD_2) OR (hwCfgMethod = CFG_METHOD_3) THEN (* csum offload command for RTL8101E *) tx_tcp_csum_cmd = TxIPCS | TxTCPCS; tx_udp_csum_cmd = TxIPCS | TxUDPCS; tx_ip_csum_cmd = TxIPCS; ELSE (* csum offload command for RTL8102E *) tx_tcp_csum_cmd = TxIPCS_C | TxTCPCS_C; tx_udp_csum_cmd = TxIPCS_C | TxUDPCS_C; tx_ip_csum_cmd = TxIPCS_C; END;*) (* other hw parameters*) IF hwCfgMethod = CFG_METHOD_17 THEN eri_write(0x2F8, 2, S.VAL(SET,0x1D8F), ERIAR_ExGMAC); END; IF 28 IN bios_setting THEN IF hwCfgMethod = CFG_METHOD_13 THEN IF 2 IN Read8(0xEF) THEN mdio_write1(0x1F, 0x0001); s := mdio_read(0x1B); s := s + {2}; mdio_write(0x1B, s); mdio_write1(0x1F, 0x0000); END; END; IF hwCfgMethod = CFG_METHOD_14 THEN mdio_write1(0x1F, 0x0001); s := mdio_read(0x13); s := s + {15}; mdio_write(0x13, s); mdio_write1(0x1F, 0x0000); END; END; IF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) (*IF ASPM THEN init_pci_offset_99(tp); init_pci_offset_180(tp); END;*) END; cp_cmd := cp_cmd + RxChkSum; TRACE(cp_cmd); Write16(CPlusCmd, cp_cmd); (*! ??? *) cp_cmd := Read16(CPlusCmd); TRACE(cp_cmd); IF hwCfgMethod = CFG_METHOD_17 THEN i := 0; WHILE (i < 10) & (13 IN eri_read(0x1AE, 2, ERIAR_ExGMAC)) DO INC(i); END; ASSERT(i < 10); END; Write16(RxMaxSize, S.VAL(SET,rx_buf_sz)); disable_rxdvgate; dsm(DSM_MAC_INIT); options1 := Read8(Config3); options2 := Read8(Config5); IF (options1 * (LinkUp + MagicPacket) # {}) OR (options2 * (UWF + BWF + MWF) # {}) THEN wol_enabled := TRUE; ELSE wol_enabled := FALSE; END; hw_set_rx_packet_filter; CASE hwCfgMethod OF |CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: IF ASPM THEN Write8(Config5, Read8(Config5) + {0}); Write8(Config2, Read8(Config2) + {7}); ELSE Write8(Config2, Read8(Config2) - {7}); Write8(Config5, Read8(Config5) - {0}); END; ELSE END; Write8(Cfg9346, Cfg9346_Lock); (*IF ~in_open_fun THEN Write8(ChipCmd, CmdTxEnb + CmdRxEnb); (* Enable all known interrupts by setting the interrupt mask. *) Write16(IntrMask, intr_mask); END;*) Delay(1); END hw_start; PROCEDURE open; BEGIN set_rxbufsize; (* prepare TX/RX descriptor rings *) txDescStartAddr := SetupTxRing(); rxDescStartAddr := SetupRxRing(); exit_oob; tally_counter_clear; hw_init; hw_reset; powerup_pll; hw_ephy_config; hw_phy_config; hw_start; dsm(DSM_IF_UP); (*set_speed_xmii(autoneg, speed, duplexFull);*) END open; PROCEDURE get_hw_wol; BEGIN (*! Not implemented *) END get_hw_wol; PROCEDURE init_software_variable; BEGIN get_bios_setting; CASE hwCfgMethod OF |CFG_METHOD_1,CFG_METHOD_2,CFG_METHOD_3: intr_mask := {RxDescUnavail} + {TxDescUnavail} + {TxOK} + {RxOK} + {SWInt}; ELSE intr_mask := {RxDescUnavail} + {LinkChg} + {TxOK} + {RxOK} + {SWInt}; END; IF ASPM THEN HALT(100); (*! Not implemented *) (*IF hwCfgMethod = CFG_METHOD_17 THEN org_pci_offset_99 := csi_fun0_read_byte(0x99); org_pci_offset_180 := csi_fun0_read_byte(0x180); END;*) END; IF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) (*read_config_byte(pdev, 0x80, &tp->org_pci_offset_80); read_config_byte(pdev, 0x81, &tp->org_pci_offset_81); IF (features * RTL_FEATURE_MSI # {}) & (1 IN org_pci_offset_80)) THEN use_timer_interrrupt := FALSE; ELSE use_timer_interrrupt := TRUE; END;*) ELSE use_timer_interrrupt := TRUE; END; IF hwIcVerUnknown THEN notWrRamCodeToMicroP := TRUE; notWrMcuPatchCode := TRUE; END; get_hw_wol; END init_software_variable; PROCEDURE exit_oob; BEGIN nic_reset; IF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) END; END exit_oob; PROCEDURE get_bios_setting; BEGIN bios_setting := {}; CASE hwCfgMethod OF |CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: bios_setting := Read32(0x8c); ELSE END; END get_bios_setting; PROCEDURE set_bios_setting; BEGIN CASE hwCfgMethod OF |CFG_METHOD_10,CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13,CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16,CFG_METHOD_17: Write32(0x8c,bios_setting); ELSE END; END set_bios_setting; PROCEDURE mdio_wait_for( regAddr: LONGINT; nRetries: LONGINT; delay: LONGINT; mask: SET; val: SET ); BEGIN WHILE (nRetries > 0) & (Read32(regAddr) * mask # val) DO Delay(delay); DEC(nRetries); END; ASSERT(nRetries > 0); END mdio_wait_for; (* Writing to MDIO of the PHY *) PROCEDURE mdio_write(regAddr: LONGINT; data: SET); VAR d: LONGINT; BEGIN IF hwCfgMethod # CFG_METHOD_17 THEN d := LSH(S.VAL(LONGINT,(S.VAL(SET,regAddr)*PHYAR_Reg_Mask)),PHYAR_Reg_shift); Write32(PHYAR,PHYAR_Write + S.VAL(SET,d) + (data*PHYAR_Data_Mask)); (* Check if the RTL8101 has completed writing to the specified MII register *) mdio_wait_for(PHYAR,10,1,PHYAR_Flag,{}); Delay(1); ELSE HALT(100); (*! not implemented *) END; END mdio_write; PROCEDURE mdio_write1(regAddr: LONGINT; data: LONGINT); BEGIN mdio_write(regAddr,S.VAL(SET,data)); END mdio_write1; (* Reading from MDIO of the PHY *) PROCEDURE mdio_read(regAddr: LONGINT): SET; VAR d, i: LONGINT; BEGIN IF hwCfgMethod # CFG_METHOD_17 THEN d := LSH(S.VAL(LONGINT,S.VAL(SET,regAddr)*PHYAR_Reg_Mask),PHYAR_Reg_shift); Write32(PHYAR,PHYAR_Read + S.VAL(SET,d)); (* Check if the RTL8101 has completed retrieving data from the specified MII register *) i := 0; WHILE (i < 10) & (Read32(PHYAR) * PHYAR_Flag = {}) DO Delay(1); INC(i); END; ASSERT(i < 10); Delay(1); RETURN Read32(PHYAR) * PHYAR_Data_Mask; ELSE HALT(100); (*! not implemented *) END; END mdio_read; PROCEDURE phyio_write(regAddr: LONGINT; data: SET); VAR d, i: LONGINT; BEGIN d := LSH(S.VAL(LONGINT,S.VAL(SET,regAddr)*PHYIO_Reg_Mask),PHYIO_Reg_shift); Write32(PHYIO,PHYIO_Write + S.VAL(SET,d) + (data * PHYIO_Data_Mask)); (* Check if the RTL8101 has completed writing to the specified MII register *) i := 0; WHILE (i < 10) & (Read32(PHYIO) * PHYIO_Flag # {}) DO Delay(1); INC(i); END; ASSERT(i < 10); Delay(1); END phyio_write; PROCEDURE xmii_reset_enable; VAR i: LONGINT; BEGIN mdio_write(0x1f,{}); mdio_write(NetworkMii.BMCR,mdio_read(NetworkMii.BMCR)+NetworkMii.BMCR_Reset); i := 0; WHILE (i < 2500) & (mdio_read(NetworkMii.BMSR) * NetworkMii.BMCR_Reset # {}) DO Delay(1); INC(i); END; ASSERT(i < 2500); END xmii_reset_enable; PROCEDURE check_hw_phy_mcu_code_ver(): BOOLEAN; VAR sw_ram_code_ver, hw_ram_code_ver: SET; BEGIN sw_ram_code_ver := S.VAL(SET,0xFFFF); hw_ram_code_ver := {}; IF hwCfgMethod = CFG_METHOD_17 THEN sw_ram_code_ver := {0}; (*NIC_RAMCODE_VERSION_CFG_METHOD_17*) mdio_write(0x1F,S.VAL(SET,0x0A43)); mdio_write(0x13,S.VAL(SET,0x801E)); hw_ram_code_ver := mdio_read(0x14); mdio_write(0x1F,{}); END; IF hw_ram_code_ver = sw_ram_code_ver THEN hwHasWrRamCodeToMicroP := TRUE; RETURN TRUE; ELSE RETURN FALSE; END; END check_hw_phy_mcu_code_ver; PROCEDURE write_hw_phy_mcu_code_ver; VAR ver: LONGINT; BEGIN IF hwCfgMethod = CFG_METHOD_17 THEN ver := 0x0001; mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x801E); mdio_write1(0x14, ver); mdio_write1(0x1F, 0x0000); END; END write_hw_phy_mcu_code_ver; PROCEDURE init_hw_phy_mcu; CONST Addr_10 = [0x1f,0x1f,0x1e,0x16,0x16,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x15,0x19,0x16,0x16,0x1f,0x17,0x1f,0x1e,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x19,0x18,0x1f,0x17,0x1f,0x05,0x06,0x05,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x06]; Val_10 = [0x0000,0x0007,0x0023,0x0306,0x0307,0x000e,0x000a,0x0010,0x0008,0x0018,0x4801,0x0019,0x6801,0x001a,0x66a1,0x001f,0x0000,0x0020,0x0000,0x0021,0x0000,0x0022,0x0000,0x0023,0x0000,0x0024,0x0000,0x0025,0x64a1,0x0026,0x40ea,0x0027,0x4503,0x0028,0x9f00,0x0029,0xa631,0x002a,0x9717,0x002b,0x302c,0x002c,0x4802,0x002d,0x58da,0x002e,0x400d,0x002f,0x4488,0x0030,0x9e00,0x0031,0x63c8,0x0032,0x6481,0x0033,0x0000,0x0034,0x0000,0x0035,0x0000,0x0036,0x0000,0x0037,0x0000,0x0038,0x0000,0x0039,0x0000,0x003a,0x0000,0x003b,0x63e8,0x003c,0x7d00,0x003d,0x59d4,0x003e,0x63f8,0x0040,0x64a1,0x0041,0x30de,0x0044,0x480f,0x0045,0x6800,0x0046,0x6680,0x0047,0x7c10,0x0048,0x63c8,0x0049,0x0000,0x004a,0x0000,0x004b,0x0000,0x004c,0x0000,0x004d,0x0000,0x004e,0x0000,0x004f,0x40ea,0x0050,0x4503,0x0051,0x58ca,0x0052,0x63c8,0x0053,0x63d8,0x0054,0x66a0,0x0055,0x9f00,0x0056,0x3000,0x006e,0x9afa,0x00a1,0x3044,0x00ab,0x5820,0x00ac,0x5e04,0x00ad,0xb60c,0x00af,0x000a,0x00b2,0x30b9,0x00b9,0x4408,0x00ba,0x480b,0x00bb,0x5e00,0x00bc,0x405f,0x00bd,0x4448,0x00be,0x4020,0x00bf,0x4468,0x00c0,0x9c02,0x00c1,0x58a0,0x00c2,0xb605,0x00c3,0xc0d3,0x00c4,0x00e6,0x00c5,0xdaec,0x00c6,0x00fa,0x00c7,0x9df9,0x00c8,0x307a,0x0112,0x6421,0x0113,0x7c08,0x0114,0x63f0,0x0115,0x4003,0x0116,0x4418,0x0117,0x9b00,0x0118,0x6461,0x0119,0x64e1,0x011a,0x0000,0x0150,0x6461,0x0151,0x4003,0x0152,0x4540,0x0153,0x9f00,0x0155,0x6421,0x0156,0x64a1,0x021e,0x5410,0x0225,0x5400,0x023d,0x4050,0x0295,0x6c08,0x02bd,0xa523,0x02be,0x32ca,0x02ca,0x48b3,0x02cb,0x4020,0x02cc,0x4823,0x02cd,0x4510,0x02ce,0xb63a,0x02cf,0x7dc8,0x02d6,0x9bf8,0x02d8,0x85f6,0x02d9,0x32e0,0x02e0,0x4834,0x02e1,0x6c08,0x02e2,0x4020,0x02e3,0x4824,0x02e4,0x4520,0x02e5,0x4008,0x02e6,0x4560,0x02e7,0x9d04,0x02e8,0x48c4,0x02e9,0x0000,0x02ea,0x4844,0x02eb,0x7dc8,0x02f0,0x9cf7,0x02f1,0xdf94,0x02f2,0x0002,0x02f3,0x6810,0x02f4,0xb614,0x02f5,0xc42b,0x02f6,0x00d4,0x02f7,0xc455,0x02f8,0x0093,0x02f9,0x92ee,0x02fa,0xefed,0x02fb,0x3312,0x0312,0x49b5,0x0313,0x7d00,0x0314,0x4d00,0x0315,0x6810,0x031e,0x404f,0x031f,0x44c8,0x0320,0xd64f,0x0321,0x00e7,0x0322,0x7c08,0x0323,0x8203,0x0324,0x4d48,0x0325,0x3327,0x0326,0x4d40,0x0327,0xc8d7,0x0328,0x0003,0x0329,0x7c20,0x032a,0x4c20,0x032b,0xc8ed,0x032c,0x00f4,0x032d,0x82b3,0x032e,0xd11d,0x032f,0x00b1,0x0330,0xde18,0x0331,0x0008,0x0332,0x91ee,0x0333,0x3339,0x033a,0x4064,0x0340,0x9e06,0x0341,0x7c08,0x0342,0x8203,0x0343,0x4d48,0x0344,0x3346,0x0345,0x4d40,0x0346,0xd11d,0x0347,0x0099,0x0348,0xbb17,0x0349,0x8102,0x034a,0x334d,0x034b,0xa22c,0x034c,0x3397,0x034d,0x91f2,0x034e,0xc218,0x034f,0x00f0,0x0350,0x3397,0x0351,0x0000,0x0364,0xbc05,0x0367,0xa1fc,0x0368,0x3377,0x0369,0x328b,0x036a,0x0000,0x0377,0x4b97,0x0378,0x6818,0x0379,0x4b07,0x037a,0x40ac,0x037b,0x4445,0x037c,0x404e,0x037d,0x4461,0x037e,0x9c09,0x037f,0x63da,0x0380,0x5440,0x0381,0x4b98,0x0382,0x7c60,0x0383,0x4c00,0x0384,0x4b08,0x0385,0x63d8,0x0386,0x338d,0x0387,0xd64f,0x0388,0x0080,0x0389,0x820c,0x038a,0xa10b,0x038b,0x9df3,0x038c,0x3395,0x038d,0xd64f,0x038e,0x00f9,0x038f,0xc017,0x0390,0x0005,0x0391,0x6c0b,0x0392,0xa103,0x0393,0x6c08,0x0394,0x9df9,0x0395,0x6c08,0x0396,0x3397,0x0399,0x6810,0x03a4,0x7c08,0x03a5,0x8203,0x03a6,0x4d08,0x03a7,0x33a9,0x03a8,0x4d00,0x03a9,0x9bfa,0x03aa,0x33b6,0x03bb,0x4056,0x03bc,0x44e9,0x03bd,0x4054,0x03be,0x44f8,0x03bf,0xd64f,0x03c0,0x0037,0x03c1,0xbd37,0x03c2,0x9cfd,0x03c3,0xc639,0x03c4,0x0011,0x03c5,0x9b03,0x03c6,0x7c01,0x03c7,0x4c01,0x03c8,0x9e03,0x03c9,0x7c20,0x03ca,0x4c20,0x03cb,0x9af4,0x03cc,0x7c12,0x03cd,0x4c52,0x03ce,0x4470,0x03cf,0x7c12,0x03d0,0x4c40,0x03d1,0x33bf,0x03d6,0x4047,0x03d7,0x4469,0x03d8,0x492b,0x03d9,0x4479,0x03da,0x7c09,0x03db,0x8203,0x03dc,0x4d48,0x03dd,0x33df,0x03de,0x4d40,0x03df,0xd64f,0x03e0,0x0017,0x03e1,0xbd17,0x03e2,0x9b03,0x03e3,0x7c20,0x03e4,0x4c20,0x03e5,0x88f5,0x03e6,0xc428,0x03e7,0x0008,0x03e8,0x9af2,0x03e9,0x7c12,0x03ea,0x4c52,0x03eb,0x4470,0x03ec,0x7c12,0x03ed,0x4c40,0x03ee,0x33da,0x03ef,0x3312,0x0306,0x0300,0x0000,0x2179,0x0007,0x0040,0x0645,0xe200,0x0655,0x9000,0x0d05,0xbe00,0x0d15,0xd300,0x0d25,0xfe00,0x0d35,0x4000,0x0d45,0x7f00,0x0d55,0x1000,0x0d65,0x0000,0x0d75,0x8200,0x0d85,0x0000,0x0d95,0x7000,0x0da5,0x0f00,0x0db5,0x0100,0x0dc5,0x9b00,0x0dd5,0x7f00,0x0de5,0xe000,0x0df5,0xef00,0x16d5,0xe200,0x16e5,0xab00,0x2904,0x4000,0x2914,0x7f00,0x2924,0x0100,0x2934,0x2000,0x2944,0x0000,0x2954,0x4600,0x2964,0xfc00,0x2974,0x0000,0x2984,0x5000,0x2994,0x9d00,0x29a4,0xff00,0x29b4,0x4000,0x29c4,0x7f00,0x29d4,0x0000,0x29e4,0x2000,0x29f4,0x0000,0x2a04,0xe600,0x2a14,0xff00,0x2a24,0x0000,0x2a34,0x5000,0x2a44,0x8500,0x2a54,0x7f00,0x2a64,0xac00,0x2a74,0x0800,0x2a84,0xfc00,0x2a94,0xe000,0x2aa4,0x7400,0x2ab4,0x4000,0x2ac4,0x7f00,0x2ad4,0x0100,0x2ae4,0xff00,0x2af4,0x0000,0x2b04,0x4400,0x2b14,0xfc00,0x2b24,0x0000,0x2b34,0x4000,0x2b44,0x9d00,0x2b54,0xff00,0x2b64,0x4000,0x2b74,0x7f00,0x2b84,0x0000,0x2b94,0xff00,0x2ba4,0x0000,0x2bb4,0xfc00,0x2bc4,0xff00,0x2bd4,0x0000,0x2be4,0x4000,0x2bf4,0x8900,0x2c04,0x8300,0x2c14,0xe000,0x2c24,0x0000,0x2c34,0xac00,0x2c44,0x0800,0x2c54,0xfa00,0x2c64,0xe100,0x2c74,0x7f00,0x0001,0x0000,0x2100,0x0005,0xfff6,0x0080,0x8000,0xd480,0xc1e4,0x8b9a,0xe58b,0x9bee,0x8b83,0x41bf,0x8b88,0xec00,0x19a9,0x8b90,0xf9ee,0xfff6,0x00ee,0xfff7,0xffe0,0xe140,0xe1e1,0x41f7,0x2ff6,0x28e4,0xe140,0xe5e1,0x41f7,0x0002,0x020c,0x0202,0x1d02,0x0230,0x0202,0x4002,0x028b,0x0280,0x6c02,0x8085,0xe08b,0x88e1,0x8b89,0x1e01,0xe18b,0x8a1e,0x01e1,0x8b8b,0x1e01,0xe18b,0x8c1e,0x01e1,0x8b8d,0x1e01,0xe18b,0x8e1e,0x01a0,0x00c7,0xaec3,0xf8e0,0x8b8d,0xad20,0x10ee,0x8b8d,0x0002,0x1310,0x0280,0xc602,0x1f0c,0x0227,0x49fc,0x04f8,0xe08b,0x8ead,0x200b,0xf620,0xe48b,0x8e02,0x852d,0x021b,0x67ad,0x2211,0xf622,0xe48b,0x8e02,0x2ba5,0x022a,0x2402,0x82e5,0x022a,0xf0ad,0x2511,0xf625,0xe48b,0x8e02,0x8445,0x0204,0x0302,0x19cc,0x022b,0x5bfc,0x04ee,0x8b8d,0x0105,0xf8f9,0xfae0,0x8b81,0xac26,0x08e0,0x8b81,0xac21,0x02ae,0x6bee,0xe0ea,0x00ee,0xe0eb,0x00e2,0xe07c,0xe3e0,0x7da5,0x1111,0x15d2,0x60d6,0x6666,0x0207,0x6cd2,0xa0d6,0xaaaa,0x0207,0x6c02,0x201d,0xae44,0xa566,0x6602,0xae38,0xa5aa,0xaa02,0xae32,0xeee0,0xea04,0xeee0,0xeb06,0xe2e0,0x7ce3,0xe07d,0xe0e0,0x38e1,0xe039,0xad2e,0x21ad,0x3f13,0xe0e4,0x14e1,0xe415,0x6880,0xe4e4,0x14e5,0xe415,0x0220,0x1dae,0x0bac,0x3e02,0xae06,0x0281,0x4602,0x2057,0xfefd,0xfc04,0xf8e0,0x8b81,0xad26,0x0302,0x20a7,0xe08b,0x81ad,0x2109,0xe08b,0x2eac,0x2003,0x0281,0x61fc,0x04f8,0xe08b,0x81ac,0x2505,0x0222,0xaeae,0x0302,0x8172,0xfc04,0xf8f9,0xfaef,0x69fa,0xe086,0x20a0,0x8016,0xe086,0x21e1,0x8b33,0x1b10,0x9e06,0x0223,0x91af,0x8252,0xee86,0x2081,0xaee4,0xa081,0x1402,0x2399,0xbf25,0xcc02,0x2d21,0xee86,0x2100,0xee86,0x2082,0xaf82,0x52a0,0x8232,0xe086,0x21e1,0x8b32,0x1b10,0x9e06,0x0223,0x91af,0x8252,0xee86,0x2100,0xd000,0x0282,0x5910,0xa004,0xf9e0,0x861f,0xa000,0x07ee,0x8620,0x83af,0x8178,0x0224,0x0102,0x2399,0xae72,0xa083,0x4b1f,0x55d0,0x04bf,0x8615,0x1a90,0x0c54,0xd91e,0x31b0,0xf4e0,0xe022,0xe1e0,0x23ad,0x2e0c,0xef02,0xef12,0x0e44,0xef23,0x0e54,0xef21,0xe6e4,0x2ae7,0xe42b,0xe2e4,0x28e3,0xe429,0x6d20,0x00e6,0xe428,0xe7e4,0x29bf,0x25ca,0x022d,0x21ee,0x8620,0x84ee,0x8621,0x00af,0x8178,0xa084,0x19e0,0x8621,0xe18b,0x341b,0x109e,0x0602,0x2391,0xaf82,0x5202,0x241f,0xee86,0x2085,0xae08,0xa085,0x02ae,0x0302,0x2442,0xfeef,0x96fe,0xfdfc,0x04f8,0xf9fa,0xef69,0xfad1,0x801f,0x66e2,0xe0ea,0xe3e0,0xeb5a,0xf81e,0x20e6,0xe0ea,0xe5e0,0xebd3,0x05b3,0xfee2,0xe07c,0xe3e0,0x7dad,0x3703,0x7dff,0xff0d,0x581c,0x55f8,0xef46,0x0282,0xc7ef,0x65ef,0x54fc,0xac30,0x2b11,0xa188,0xcabf,0x860e,0xef10,0x0c11,0x1a91,0xda19,0xdbf8,0xef46,0x021e,0x17ef,0x54fc,0xad30,0x0fef,0x5689,0xde19,0xdfe2,0x861f,0xbf86,0x161a,0x90de,0xfeef,0x96fe,0xfdfc,0x04ac,0x2707,0xac37,0x071a,0x54ae,0x11ac,0x3707,0xae00,0x1a54,0xac37,0x07d0,0x01d5,0xffff,0xae02,0xd000,0x04f8,0xe08b,0x83ad,0x2444,0xe0e0,0x22e1,0xe023,0xad22,0x3be0,0x8abe,0xa000,0x0502,0x28de,0xae42,0xa001,0x0502,0x28f1,0xae3a,0xa002,0x0502,0x8344,0xae32,0xa003,0x0502,0x299a,0xae2a,0xa004,0x0502,0x29ae,0xae22,0xa005,0x0502,0x29d7,0xae1a,0xa006,0x0502,0x29fe,0xae12,0xee8a,0xc000,0xee8a,0xc100,0xee8a,0xc600,0xee8a,0xbe00,0xae00,0xfc04,0xf802,0x2a67,0xe0e0,0x22e1,0xe023,0x0d06,0x5803,0xa002,0x02ae,0x2da0,0x0102,0xae2d,0xa000,0x4de0,0xe200,0xe1e2,0x01ad,0x2444,0xe08a,0xc2e4,0x8ac4,0xe08a,0xc3e4,0x8ac5,0xee8a,0xbe03,0xe08b,0x83ad,0x253a,0xee8a,0xbe05,0xae34,0xe08a,0xceae,0x03e0,0x8acf,0xe18a,0xc249,0x05e5,0x8ac4,0xe18a,0xc349,0x05e5,0x8ac5,0xee8a,0xbe05,0x022a,0xb6ac,0x2012,0x0283,0xbaac,0x200c,0xee8a,0xc100,0xee8a,0xc600,0xee8a,0xbe02,0xfc04,0xd000,0x0283,0xcc59,0x0f39,0x02aa,0x04d0,0x01ae,0x02d0,0x0004,0xf9fa,0xe2e2,0xd2e3,0xe2d3,0xf95a,0xf7e6,0xe2d2,0xe7e2,0xd3e2,0xe02c,0xe3e0,0x2df9,0x5be0,0x1e30,0xe6e0,0x2ce7,0xe02d,0xe2e2,0xcce3,0xe2cd,0xf95a,0x0f6a,0x50e6,0xe2cc,0xe7e2,0xcde0,0xe03c,0xe1e0,0x3def,0x64fd,0xe0e2,0xcce1,0xe2cd,0x580f,0x5af0,0x1e02,0xe4e2,0xcce5,0xe2cd,0xfde0,0xe02c,0xe1e0,0x2d59,0xe05b,0x1f1e,0x13e4,0xe02c,0xe5e0,0x2dfd,0xe0e2,0xd2e1,0xe2d3,0x58f7,0x5a08,0x1e02,0xe4e2,0xd2e5,0xe2d3,0xef46,0xfefd,0x04f8,0xf9fa,0xef69,0xe0e0,0x22e1,0xe023,0x58c4,0xe18b,0x6e1f,0x109e,0x58e4,0x8b6e,0xad22,0x22ac,0x2755,0xac26,0x02ae,0x1ad1,0x06bf,0x3bba,0x022d,0xc1d1,0x07bf,0x3bbd,0x022d,0xc1d1,0x07bf,0x3bc0,0x022d,0xc1ae,0x30d1,0x03bf,0x3bc3,0x022d,0xc1d1,0x00bf,0x3bc6,0x022d,0xc1d1,0x00bf,0x84e9,0x022d,0xc1d1,0x0fbf,0x3bba,0x022d,0xc1d1,0x01bf,0x3bbd,0x022d,0xc1d1,0x01bf,0x3bc0,0x022d,0xc1ef,0x96fe,0xfdfc,0x04d1,0x00bf,0x3bc3,0x022d,0xc1d0,0x1102,0x2bfb,0x5903,0xef01,0xd100,0xa000,0x02d1,0x01bf,0x3bc6,0x022d,0xc1d1,0x11ad,0x2002,0x0c11,0xad21,0x020c,0x12bf,0x84e9,0x022d,0xc1ae,0xc870,0xe426,0x0284,0xf005,0xf8fa,0xef69,0xe0e2,0xfee1,0xe2ff,0xad2d,0x1ae0,0xe14e,0xe1e1,0x4fac,0x2d22,0xf603,0x0203,0x3bf7,0x03f7,0x06bf,0x8561,0x022d,0x21ae,0x11e0,0xe14e,0xe1e1,0x4fad,0x2d08,0xbf85,0x6c02,0x2d21,0xf606,0xef96,0xfefc,0x04f8,0xfaef,0x69e0,0xe000,0xe1e0,0x01ad,0x271f,0xd101,0xbf85,0x5e02,0x2dc1,0xe0e0,0x20e1,0xe021,0xad20,0x0ed1,0x00bf,0x855e,0x022d,0xc1bf,0x3b96,0x022d,0x21ef,0x96fe,0xfc04,0x00e2,0x34a7,0x25e5,0x0a1d,0xe50a,0x2ce5,0x0a6d,0xe50a,0x1de5,0x0a1c,0xe50a,0x2da7,0x5500,0x8b94,0x84ec]; Addr_11_12_13 = [0x1f,0x1f,0x19,0x1c,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1f,0x1c,0x19,0x1f]; Val_11_12_13 = [0x0004,0x0004,0x7070,0x0600,0x9700,0x7d00,0x6900,0x7d00,0x6800,0x4899,0x7c1f,0x4c00,0x7c1f,0x4c01,0x8000,0x7fe0,0x4c00,0x4007,0x4400,0x4800,0x7c1f,0x4c00,0x5310,0x6000,0x6800,0x6736,0x0000,0x0000,0x571f,0x5ffb,0xaa03,0x5b58,0x301e,0x5b64,0xa6fc,0xdcdb,0x0014,0xd9a9,0x0013,0xd16b,0x0011,0xb40e,0xd06b,0x000c,0xb206,0x7c01,0x5800,0x7c04,0x5c00,0x301a,0x7c01,0x5801,0x7c04,0x5c04,0x301e,0x314d,0x31f0,0x7fe0,0x4c20,0x6004,0x5310,0x4833,0x7c1f,0x4c00,0x7c1f,0x4c08,0x8300,0x6800,0x6600,0x0000,0x0000,0xb90c,0x30d3,0x7fe0,0x4de0,0x7c04,0x6000,0x6800,0x6736,0x0000,0x0000,0x5310,0x300b,0x7fe0,0x4c60,0x6803,0x6520,0x0000,0x0000,0xaf03,0x6015,0x3059,0x6017,0x57e0,0x580c,0x588c,0x7ffc,0x5fa3,0x4827,0x7c1f,0x4c00,0x7c1f,0x4c10,0x8400,0x7c30,0x6020,0x48bf,0x7c1f,0x4c00,0x7c1f,0x4c01,0xad09,0x7c03,0x5c03,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0xad2c,0xd6cf,0x0002,0x80f4,0x7fe0,0x4c80,0x7c20,0x5c20,0x481e,0x7c1f,0x4c00,0x7c1f,0x4c02,0xad0a,0x7c03,0x5c03,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x5310,0x8d02,0x4401,0x81f4,0x3114,0x7fe0,0x4d00,0x4832,0x7c1f,0x4c00,0x7c1f,0x4c10,0x7c08,0x6000,0xa4b7,0xd9b3,0xfffe,0x7fe0,0x4d20,0x7e00,0x6200,0x3045,0x7fe0,0x4d40,0x7c40,0x6000,0x4401,0x5210,0x4833,0x7c08,0x4c00,0x7c08,0x4c08,0x8300,0x5f80,0x55e0,0xc06f,0x0005,0xd9b3,0xfffd,0x7c40,0x6040,0x7fe0,0x4d60,0x57e0,0x4814,0x7c04,0x4c00,0x7c04,0x4c04,0x8200,0x7c03,0x5c03,0x0000,0x0000,0x0000,0x0000,0x0000,0xad02,0x4400,0xc0e9,0x0003,0xadd8,0x30c6,0x3078,0x7fe0,0x4dc0,0x6730,0x0000,0x0000,0xd09d,0x0002,0xb4fe,0x7fe0,0x4d80,0x6802,0x6600,0x0000,0x0000,0x7c08,0x6000,0x486c,0x7c1f,0x4c00,0x7c1f,0x4c01,0x9503,0x7e00,0x6200,0x571f,0x5fbb,0xaa03,0x5b58,0x30e9,0x5b64,0xcdab,0xff5b,0xcd8d,0xff59,0xd96b,0xff57,0xd0a0,0xffdb,0xcba0,0x0003,0x80f0,0x30f6,0x3109,0x7fe0,0x4ce0,0x7d30,0x6530,0x0000,0x0000,0x7ce0,0x5400,0x4832,0x7c1f,0x4c00,0x7c1f,0x4c08,0x7c08,0x6008,0x8300,0xb902,0x30d3,0x308f,0x7fe0,0x4da0,0x57a0,0x590c,0x5fa2,0xcba4,0x0005,0xcd8d,0x0003,0x80fc,0x0000,0x7fe0,0x4ca0,0xb603,0x7c10,0x6010,0x7c1f,0x541f,0x7ffc,0x5fb3,0x9403,0x7c03,0x5c03,0xaa05,0x7c80,0x5800,0x5b58,0x3128,0x7c80,0x5800,0x5b64,0x4827,0x7c1f,0x4c00,0x7c1f,0x4c10,0x8400,0x7c10,0x6000,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x7fe0,0x4cc0,0x7d00,0x6400,0x7ffc,0x5fbb,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x7e00,0x6a00,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x7e00,0x6800,0x30f6,0x7fe0,0x4e00,0x4007,0x4400,0x5310,0x6800,0x6736,0x0000,0x0000,0x570f,0x5fff,0xaa03,0x585b,0x315c,0x5867,0x9402,0x6200,0xcda3,0x009d,0xcd85,0x009b,0xd96b,0x0099,0x96e9,0x6800,0x6736,0x7fe0,0x4e20,0x96e4,0x8b04,0x7c08,0x5008,0xab03,0x7c08,0x5000,0x6801,0x6776,0x0000,0x0000,0xdb7c,0xfff0,0x0000,0x7fe1,0x4e40,0x4837,0x4418,0x41c7,0x7fe0,0x4e40,0x7c40,0x5400,0x7c1f,0x4c01,0x7c1f,0x4c01,0x8fc9,0xd2a0,0x004a,0x9203,0xa041,0x3184,0x7fe1,0x4e60,0x489c,0x4628,0x7fe0,0x4e60,0x7e28,0x4628,0x7c40,0x5400,0x7c01,0x5800,0x7c04,0x5c00,0x41e8,0x7c1f,0x4c01,0x7c1f,0x4c01,0x8fb0,0xb241,0xa02a,0x319d,0x7fe0,0x4ea0,0x7c02,0x4402,0x4448,0x4894,0x7c1f,0x4c01,0x7c1f,0x4c03,0x4824,0x7c1f,0x4c07,0x41ef,0x41ff,0x4891,0x7c1f,0x4c07,0x7c1f,0x4c17,0x8400,0x8ef8,0x41c7,0x8f95,0x92d5,0xa10f,0xd480,0x0008,0xd580,0xffb9,0xa202,0x31b8,0x7c04,0x4404,0x31b8,0xd484,0xfff3,0xd484,0xfff1,0x314d,0x7fe0,0x4ee0,0x7c40,0x5400,0x4488,0x41cf,0x314d,0x7fe0,0x4ec0,0x48f3,0x7c1f,0x4c01,0x7c1f,0x4c09,0x4508,0x41c7,0x8f24,0xd218,0x0022,0xd2a4,0xff9f,0x31d9,0x7fe0,0x4e80,0x4832,0x7c1f,0x4c01,0x7c1f,0x4c11,0x4428,0x7c40,0x5440,0x7c01,0x5801,0x7c04,0x5c04,0x41e8,0xa4b3,0x31ee,0x6800,0x6736,0x0000,0x0000,0x570f,0x5fff,0xaa03,0x585b,0x31fa,0x5867,0xbcf6,0x300b,0x300b,0x314d,0x0004,0x0200,0x7030,0x0000]; Addr_14 = [0x1f,0x1f,0x19,0x1c,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1f,0x1c,0x19,0x1f]; Val_14 = [0x0004,0x0004,0x7070,0x0600,0x9700,0x7d00,0x6900,0x7d00,0x6800,0x4899,0x7c1f,0x4c00,0x7c1f,0x4c01,0x8000,0x7fe0,0x4c00,0x4007,0x4400,0x4800,0x7c1f,0x4c00,0x5310,0x6000,0x6800,0x6736,0x0000,0x0000,0x571f,0x5ffb,0xaa03,0x5b58,0x301e,0x5b64,0xa6fc,0xdcdb,0x0015,0xb915,0xb511,0xd16b,0x000f,0xb40f,0xd06b,0x000d,0xb206,0x7c01,0x5800,0x7c04,0x5c00,0x301a,0x7c01,0x5801,0x7c04,0x5c04,0x301e,0x3079,0x30f1,0x3199,0x7fe0,0x4c60,0x6803,0x6420,0x0000,0x0000,0xaf03,0x6015,0x3040,0x6017,0x57e0,0x580c,0x588c,0x5fa3,0x0000,0x4827,0x7c1f,0x4c00,0x7c1f,0x4c10,0x8400,0x7c30,0x6020,0x48bf,0x7c1f,0x4c00,0x7c1f,0x4c01,0xd6cf,0x0002,0x80fe,0x7fe0,0x4c80,0x7c20,0x5c20,0x481e,0x7c1f,0x4c00,0x7c1f,0x4c02,0x5310,0x81ff,0x30ba,0x7fe0,0x4d00,0x4832,0x7c1f,0x4c00,0x7c1f,0x4c10,0x7c08,0x6000,0xa4cc,0xd9b3,0xfffe,0x7fe0,0x4d20,0x7e00,0x6200,0x300b,0x7fe0,0x4dc0,0x0000,0x0000,0xd09d,0x0002,0xb4fe,0x7fe0,0x4d80,0x7c04,0x6004,0x5310,0x6802,0x6720,0x0000,0x0000,0x7c08,0x6000,0x486c,0x7c1f,0x4c00,0x7c1f,0x4c01,0x9503,0x7e00,0x6200,0x571f,0x5fbb,0xaa03,0x5b58,0x3092,0x5b64,0xcdab,0xff78,0xcd8d,0xff76,0xd96b,0xff74,0xd0a0,0xffd9,0xcba0,0x0003,0x80f0,0x309f,0x30ac,0x7fe0,0x4ce0,0x4832,0x7c1f,0x4c00,0x7c1f,0x4c08,0x7c08,0x6008,0x8300,0xb902,0x3079,0x3061,0x7fe0,0x4da0,0x6400,0x0000,0x0000,0x57a0,0x590c,0x5fa3,0x0000,0xcba4,0x0004,0xcd8d,0x0002,0x80fc,0x7fe0,0x4ca0,0xb603,0x7c10,0x6010,0x7c1f,0x541f,0x5fb3,0xaa05,0x7c80,0x5800,0x5b58,0x30ca,0x7c80,0x5800,0x5b64,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x4827,0x7c1f,0x4c00,0x7c1f,0x4c10,0x8400,0x7c10,0x6000,0x7fe0,0x4cc0,0x5fbb,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x7ce0,0x5400,0x6720,0x0000,0x0000,0x7e00,0x6a00,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x7e00,0x6800,0x309f,0x7fe0,0x4e00,0x4007,0x4400,0x5310,0x6800,0x6736,0x0000,0x0000,0x570f,0x5fff,0xaa03,0x585b,0x3100,0x5867,0x9403,0x7e00,0x6200,0xcda3,0x002d,0xcd85,0x002b,0xd96b,0x0029,0x9629,0x6800,0x6736,0x0000,0x0000,0x9624,0x7fe0,0x4e20,0x8b04,0x7c08,0x5008,0xab03,0x7c08,0x5000,0x6801,0x6776,0x0000,0x0000,0xdb7c,0xffee,0x0000,0x7fe1,0x4e40,0x4837,0x4418,0x41c7,0x7fe0,0x4e40,0x7c40,0x5400,0x7c1f,0x4c01,0x7c1f,0x4c01,0x8f07,0xd2a0,0x004c,0x9205,0xa043,0x312b,0x300b,0x30f1,0x7fe1,0x4e60,0x489c,0x4628,0x7fe0,0x4e60,0x7e28,0x4628,0x7c40,0x5400,0x7c01,0x5800,0x7c04,0x5c00,0x41e8,0x7c1f,0x4c01,0x7c1f,0x4c01,0x8fec,0xb241,0xa02a,0x3146,0x7fe0,0x4ea0,0x7c02,0x4402,0x4448,0x4894,0x7c1f,0x4c01,0x7c1f,0x4c03,0x4824,0x7c1f,0x4c07,0x41ef,0x41ff,0x4891,0x7c1f,0x4c07,0x7c1f,0x4c17,0x8400,0x8ef8,0x41c7,0x8fd1,0x92d5,0xa10f,0xd480,0x0008,0xd580,0xffb7,0xa202,0x3161,0x7c04,0x4404,0x3161,0xd484,0xfff3,0xd484,0xfff1,0x30f1,0x7fe0,0x4ee0,0x7c40,0x5400,0x4488,0x41cf,0x30f1,0x7fe0,0x4ec0,0x48f3,0x7c1f,0x4c01,0x7c1f,0x4c09,0x4508,0x41c7,0x8fb0,0xd218,0xffae,0xd2a4,0xff9d,0x3182,0x7fe0,0x4e80,0x4832,0x7c1f,0x4c01,0x7c1f,0x4c11,0x4428,0x7c40,0x5440,0x7c01,0x5801,0x7c04,0x5c04,0x41e8,0xa4b3,0x3197,0x7fe0,0x4f20,0x6800,0x6736,0x0000,0x0000,0x570f,0x5fff,0xaa03,0x585b,0x31a5,0x5867,0xbcf4,0x300b,0x0004,0x0200,0x7030,0x0000]; Addr_16 = [0x1f,0x1f,0x19,0x1c,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1f,0x1c,0x19,0x1f]; Val_16 = [0x0004,0x0004,0x7070,0x0600,0x9700,0x7fe0,0x4c00,0x4007,0x4400,0x4800,0x7c1f,0x4c00,0x5310,0x6000,0x6800,0x673e,0x0000,0x0000,0x571f,0x5ffb,0xaa04,0x5b58,0x6100,0x3016,0x5b64,0x6080,0xa6fa,0xdcdb,0x0015,0xb915,0xb511,0xd16b,0x000f,0xb40f,0xd06b,0x000d,0xb206,0x7c01,0x5800,0x7c04,0x5c00,0x3010,0x7c01,0x5801,0x7c04,0x5c04,0x3016,0x307e,0x30f4,0x319f,0x7fe0,0x4c60,0x6803,0x7d00,0x6900,0x6520,0x0000,0x0000,0xaf03,0x6115,0x303a,0x6097,0x57e0,0x580c,0x588c,0x5f80,0x4827,0x7c1f,0x4c00,0x7c1f,0x4c10,0x8400,0x7c30,0x6020,0x48bf,0x7c1f,0x4c00,0x7c1f,0x4c01,0xb802,0x3053,0x7c08,0x6808,0x0000,0x0000,0x7c10,0x6810,0xd6cf,0x0002,0x80fe,0x7fe0,0x4c80,0x7c10,0x6800,0x7c08,0x6800,0x0000,0x0000,0x7c23,0x5c23,0x481e,0x7c1f,0x4c00,0x7c1f,0x4c02,0x5310,0x81ff,0x30c1,0x7fe0,0x4d00,0x4832,0x7c1f,0x4c00,0x7c1f,0x4c10,0x7c08,0x6000,0xa4bd,0xd9b3,0x00fe,0x7fe0,0x4d20,0x7e00,0x6200,0x3001,0x7fe0,0x4dc0,0xd09d,0x0002,0xb4fe,0x7fe0,0x4d80,0x7c04,0x6004,0x6802,0x6728,0x0000,0x0000,0x7c08,0x6000,0x486c,0x7c1f,0x4c00,0x7c1f,0x4c01,0x9503,0x7e00,0x6200,0x571f,0x5fbb,0xaa05,0x5b58,0x7d80,0x6100,0x309a,0x5b64,0x7d80,0x6080,0xcdab,0x0058,0xcd8d,0x0056,0xd96b,0x0054,0xd0a0,0x00d8,0xcba0,0x0003,0x80ec,0x30a7,0x30b4,0x7fe0,0x4ce0,0x4832,0x7c1f,0x4c00,0x7c1f,0x4c08,0x7c08,0x6008,0x8300,0xb902,0x307e,0x3068,0x7fe0,0x4da0,0x6628,0x0000,0x0000,0x56a0,0x590c,0x5fa0,0xcba4,0x0004,0xcd8d,0x0002,0x80fc,0x7fe0,0x4ca0,0x7c08,0x6408,0x0000,0x0000,0x7d00,0x6800,0xb603,0x7c10,0x6010,0x7d1f,0x551f,0x5fb3,0xaa05,0x7c80,0x5800,0x5b58,0x30d7,0x7c80,0x5800,0x5b64,0x4827,0x7c1f,0x4c00,0x7c1f,0x4c10,0x8400,0x7c10,0x6000,0x7fe0,0x4cc0,0x7d00,0x6400,0x0000,0x0000,0x5fbb,0x4824,0x7c1f,0x4c00,0x7c1f,0x4c04,0x8200,0x7ce0,0x5400,0x7d00,0x6500,0x0000,0x0000,0x30a7,0x3001,0x7fe0,0x4e00,0x4007,0x4400,0x5310,0x6800,0x673e,0x0000,0x0000,0x570f,0x5fff,0xaa05,0x585b,0x7d80,0x6100,0x3107,0x5867,0x7d80,0x6080,0x9403,0x7e00,0x6200,0xcda3,0x00e8,0xcd85,0x00e6,0xd96b,0x00e4,0x96e4,0x6800,0x673e,0x0000,0x0000,0x7fe0,0x4e20,0x96dd,0x8b04,0x7c08,0x5008,0xab03,0x7c08,0x5000,0x6801,0x677e,0x0000,0x0000,0xdb7c,0x00ee,0x0000,0x7fe1,0x4e40,0x4837,0x4418,0x41c7,0x7fe0,0x4e40,0x7c40,0x5400,0x7c1f,0x4c01,0x7c1f,0x4c01,0x8fc2,0xd2a0,0x004b,0x9204,0xa042,0x3132,0x30f4,0x7fe1,0x4e60,0x489c,0x4628,0x7fe0,0x4e60,0x7e28,0x4628,0x7c40,0x5400,0x7c01,0x5800,0x7c04,0x5c00,0x41e8,0x7c1f,0x4c01,0x7c1f,0x4c01,0x8fa8,0xb241,0xa02a,0x314c,0x7fe0,0x4ea0,0x7c02,0x4402,0x4448,0x4894,0x7c1f,0x4c01,0x7c1f,0x4c03,0x4824,0x7c1f,0x4c07,0x41ef,0x41ff,0x4891,0x7c1f,0x4c07,0x7c1f,0x4c17,0x8400,0x8ef8,0x41c7,0x8f8d,0x92d5,0xa10f,0xd480,0x0008,0xd580,0x00b8,0xa202,0x3167,0x7c04,0x4404,0x3167,0xd484,0x00f3,0xd484,0x00f1,0x30f4,0x7fe0,0x4ee0,0x7c40,0x5400,0x4488,0x41cf,0x30f4,0x7fe0,0x4ec0,0x48f3,0x7c1f,0x4c01,0x7c1f,0x4c09,0x4508,0x41c7,0x8fb0,0xd218,0x00ae,0xd2a4,0x009e,0x3188,0x7fe0,0x4e80,0x4832,0x7c1f,0x4c01,0x7c1f,0x4c11,0x4428,0x7c40,0x5440,0x7c01,0x5801,0x7c04,0x5c04,0x41e8,0xa4b3,0x319d,0x7fe0,0x4f20,0x6800,0x673e,0x0000,0x0000,0x570f,0x5fff,0xaa04,0x585b,0x6100,0x31ad,0x5867,0x6080,0xbcf2,0x3001,0x0004,0x0200,0x7030,0x0000]; VAR i: LONGINT; s: SET; BEGIN IF notWrRamCodeToMicroP THEN RETURN; END; IF check_hw_phy_mcu_code_ver() THEN RETURN; END; IF hwCfgMethod = CFG_METHOD_10 THEN mdio_write1(0x1f, 0x0000); mdio_write1(0x00, 0x1800); mdio_write1(0x1f, 0x0007); mdio_write1(0x1e, 0x0023); mdio_write1(0x17, 0x0117); mdio_write1(0x1f, 0x0007); mdio_write1(0x1E, 0x002C); mdio_write1(0x1B, 0x5000); mdio_write1(0x1f, 0x0000); mdio_write1(0x16, 0x4104); mdio_wait_for(0x1E,200,1,S.VAL(SET,0x03FF),S.VAL(SET,0x000C)); mdio_write1(0x1f, 0x0005); mdio_wait_for(0x07,200,1,{5},{}); s := mdio_read(0x07); IF 5 IN s THEN mdio_write1(0x1f, 0x0007); mdio_write1(0x1e, 0x00a1); mdio_write1(0x17, 0x1000); mdio_write1(0x17, 0x0000); mdio_write1(0x17, 0x2000); mdio_write1(0x1e, 0x002f); mdio_write1(0x18, 0x9bfb); mdio_write1(0x1f, 0x0005); mdio_write1(0x07, 0x0000); mdio_write1(0x1f, 0x0000); END; mdio_write1(0x1f, 0x0005); mdio_write1(0x05, 0xfff6); mdio_write1(0x06, 0x0080); s := mdio_read(0x00); s := s - {7}; mdio_write(0x00, s); mdio_write1(0x1f, 0x0002); s := mdio_read(0x08); s := s - {7}; mdio_write(0x08, s); FOR i := 0 TO LEN(Addr_10,0)-1 DO mdio_write1(Addr_10[i],Val_10[i]); END; s := mdio_read(0x01); s := s + {0}; mdio_write(0x01, s); mdio_write1(0x00, 0x0005); mdio_write1(0x1f, 0x0000); mdio_write1(0x1f, 0x0005); mdio_wait_for(0x00,200,1,{7},{7}); mdio_write1(0x1f, 0x0007); mdio_write1(0x1e, 0x0023); mdio_write1(0x17, 0x0116); mdio_write1(0x1f, 0x0007); mdio_write1(0x1e, 0x0028); mdio_write1(0x15, 0x0010); mdio_write1(0x1f, 0x0007); mdio_write1(0x1e, 0x0020); mdio_write1(0x15, 0x0100); mdio_write1(0x1f, 0x0007); mdio_write1(0x1e, 0x0041); mdio_write1(0x15, 0x0802); mdio_write1(0x16, 0x2185); mdio_write1(0x1f, 0x0000); ELSIF (hwCfgMethod = CFG_METHOD_11) OR (hwCfgMethod = CFG_METHOD_12) OR (hwCfgMethod = CFG_METHOD_13) THEN mdio_write1(0x1F, 0x0000); mdio_write1(0x18, 0x0310); mdio_write1(0x1F, 0x0000); Delay(20); FOR i := 0 TO LEN(Addr_11_12_13,0)-1 DO mdio_write1(Addr_11_12_13[i],Val_11_12_13[i]); END; ELSIF hwCfgMethod = CFG_METHOD_14 THEN mdio_write1(0x1F, 0x0000); mdio_write1(0x18, 0x0310); mdio_write1(0x1F, 0x0000); Delay(20); FOR i := 0 TO LEN(Addr_14,0)-1 DO mdio_write1(Addr_14[i],Val_14[i]); END; ELSIF hwCfgMethod = CFG_METHOD_16 THEN mdio_write1(0x1F, 0x0000); mdio_write1(0x18, 0x0310); Delay(20); FOR i := 0 TO LEN(Addr_16,0)-1 DO mdio_write1(Addr_16[i],Val_16[i]); END; ELSIF hwCfgMethod = CFG_METHOD_17 THEN mdio_write1(0x1f, 0x0B82); s := mdio_read(0x10); s := s + {4}; mdio_write(0x10, s); mdio_write1(0x1f, 0x0B80); mdio_wait_for(0x10,1000,1,{6},{6}); mdio_write1(0x1f, 0x0A43); mdio_write1(0x13, 0x8146); mdio_write1(0x14, 0x0300); mdio_write1(0x13, 0xB82E); mdio_write1(0x14, 0x0001); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0xb820); mdio_write1(0x14, 0x0290); mdio_write1(0x13, 0xa012); mdio_write1(0x14, 0x0000); mdio_write1(0x13, 0xa014); mdio_write1(0x14, 0x2c04); mdio_write1(0x14, 0x2c07); mdio_write1(0x14, 0x2c07); mdio_write1(0x14, 0x2c07); mdio_write1(0x14, 0xa304); mdio_write1(0x14, 0xa301); mdio_write1(0x14, 0x207e); mdio_write1(0x13, 0xa01a); mdio_write1(0x14, 0x0000); mdio_write1(0x13, 0xa006); mdio_write1(0x14, 0x0fff); mdio_write1(0x13, 0xa004); mdio_write1(0x14, 0x0fff); mdio_write1(0x13, 0xa002); mdio_write1(0x14, 0x0fff); mdio_write1(0x13, 0xa000); mdio_write1(0x14, 0x107c); mdio_write1(0x13, 0xb820); mdio_write1(0x14, 0x0210); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x0000); mdio_write1(0x14, 0x0000); mdio_write1(0x1f, 0x0B82); s := mdio_read(0x17); s := s - {0}; mdio_write(0x17, s); mdio_write1(0x1f, 0x0A43); mdio_write1(0x13, 0x8146); mdio_write1(0x14, 0x0000); mdio_write1(0x1f, 0x0B82); s := mdio_read(0x10); s := s - {4}; mdio_write(0x10, s); END; write_hw_phy_mcu_code_ver; mdio_write1(0x1F, 0x0000); hwHasWrRamCodeToMicroP := TRUE; END init_hw_phy_mcu; PROCEDURE eri_read(addr: LONGINT; len, type: LONGINT): SET; VAR i, shift, val_shift: LONGINT; mask, value1, value2: SET; BEGIN ASSERT((len > 0) & (len <= 4)); shift := 0; WHILE len > 0 DO val_shift := addr MOD ERIAR_Addr_Align; addr := S.VAL(LONGINT,S.VAL(SET,addr)-S.VAL(SET,0x3)); Write32(ERIAR,ERIAR_Read+S.VAL(SET,LSH(type,ERIAR_Type_shift))+S.VAL(SET,LSH(LONGINT(ERIAR_ByteEn),ERIAR_ByteEn_shift))+S.VAL(SET,addr)); (* Check if the RTL8101 has completed ERI read *) i := 0; Delay(1); WHILE (i < 10) & (Read32(ERIAR) * ERIAR_Flag = {}) DO Delay(1); INC(i); END; ASSERT(i < 10); IF len = 1 THEN mask := S.VAL(SET,LSH(HUGEINT(0xFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); ELSIF len = 2 THEN mask := S.VAL(SET,LSH(HUGEINT(0xFFFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); ELSIF len = 3 THEN mask := S.VAL(SET,LSH(HUGEINT(0xFFFFFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); ELSE mask := S.VAL(SET,LSH(HUGEINT(0xFFFFFFFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); END; value1 := Read32(ERIDR) * mask; value1 := S.VAL(SET,LSH(S.VAL(HUGEINT,value1),-val_shift*8)); value1 := S.VAL(SET,LSH(S.VAL(HUGEINT,value1),shift*8)); value2 := value2 + value1; IF len <= 4 - val_shift THEN len := 0; ELSE DEC(len,4 - val_shift); shift := 4 - val_shift; INC(addr,4); END; END; Delay(1); RETURN value2; END eri_read; PROCEDURE eri_write(addr: LONGINT; len: LONGINT; value: SET; type: LONGINT); VAR i, shift, val_shift: LONGINT; mask, value1, value2: SET; BEGIN ASSERT((len > 0) & (len <= 4)); shift := 0; WHILE len > 0 DO val_shift := addr MOD ERIAR_Addr_Align; addr := S.VAL(LONGINT,S.VAL(SET,addr)-S.VAL(SET,0x3)); IF len = 1 THEN mask := S.VAL(SET,LSH(HUGEINT(0xFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); ELSIF len = 2 THEN mask := S.VAL(SET,LSH(HUGEINT(0xFFFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); ELSIF len = 3 THEN mask := S.VAL(SET,LSH(HUGEINT(0xFFFFFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); ELSE mask := S.VAL(SET,LSH(HUGEINT(0xFFFFFFFF),val_shift * 8)) * S.VAL(SET,0xFFFFFFFF); END; value1 := S.VAL(SET,LSH(S.VAL(HUGEINT,value),val_shift*8)); value1 := S.VAL(SET,LSH(S.VAL(HUGEINT,value1),-shift*8)); value1 := value1 + eri_read(addr,4,type) - mask; Write32(ERIDR,value1); Write32(ERIAR,ERIAR_Write+S.VAL(SET,LSH(type,ERIAR_Type_shift))+S.VAL(SET,LSH(LONGINT(ERIAR_ByteEn),ERIAR_ByteEn_shift))+S.VAL(SET,addr)); (* Check if the RTL8101 has completed ERI write *) i := 0; Delay(1); WHILE (i < 10) & (Read32(ERIAR) * ERIAR_Flag # {}) DO Delay(1); INC(i); END; ASSERT(i < 10); IF len <= 4 - val_shift THEN len := 0; ELSE DEC(len,4 - val_shift); shift := 4 - val_shift; INC(addr,4); END; END; Delay(1); END eri_write; PROCEDURE enable_EEE; VAR s: SET; BEGIN CASE hwCfgMethod OF |CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13: eri_write(0x1B0, 2, S.VAL(SET,0xED03), ERIAR_ExGMAC); mdio_write1(0x1F, 0x0004); IF Read8(0xEF) * S.VAL(SET,0x02) # {} THEN mdio_write1(0x10, 0x731F); mdio_write1(0x19, 0x7630); ELSE mdio_write1(0x10, 0x711F); mdio_write1(0x19, 0x7030); END; mdio_write1(0x1A, 0x1506); mdio_write1(0x1B, 0x0551); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0007); mdio_write1(0x0E, 0x003C); mdio_write1(0x0D, 0x4007); mdio_write1(0x0E, 0x0002); mdio_write1(0x0D, 0x0000); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0003); mdio_write1(0x0E, 0x0015); mdio_write1(0x0D, 0x4003); mdio_write1(0x0E, 0x0002); mdio_write1(0x0D, 0x0000); mdio_write(NetworkMii.BMCR, NetworkMii.BMCR_AutoNegotiationEnable+NetworkMii.BMCR_RestartAutoNegotiation); |CFG_METHOD_14,CFG_METHOD_15,CFG_METHOD_16: eri_write(0x1B0, 2, S.VAL(SET,0xED03),ERIAR_ExGMAC); mdio_write1(0x1F, 0x0004); mdio_write1(0x10, 0x731F); mdio_write1(0x19, 0x7630); mdio_write1(0x1A, 0x1506); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0007); mdio_write1(0x0E, 0x003C); mdio_write1(0x0D, 0x4007); mdio_write1(0x0E, 0x0002); mdio_write1(0x0D, 0x0000); mdio_write(NetworkMii.BMCR, NetworkMii.BMCR_AutoNegotiationEnable + NetworkMii.BMCR_RestartAutoNegotiation); |CFG_METHOD_17: s := eri_read(0x1B0, 4, ERIAR_ExGMAC); s := s +{0,1}; eri_write(0x1B0, 4, s, ERIAR_ExGMAC); mdio_write1(0x1F, 0x0A43); s := mdio_read(0x11); mdio_write(0x11, s + {4}); mdio_write1(0x1F, 0x0A5D); mdio_write1(0x10, 0x0006); mdio_write1(0x1F, 0x0000); ELSE TRACE("No EEE support!"); RETURN; END; (*Advanced EEE*) IF hwCfgMethod = CFG_METHOD_17 THEN eri_write(0x1EA, 1, S.VAL(SET,0xFA), ERIAR_ExGMAC); mdio_write1(0x1F, 0x0A43); s := mdio_read(0x10); IF s * {10} # {} THEN mdio_write1(0x1F, 0x0A42); s := mdio_read(0x16); s := s - {1}; mdio_write(0x16, s); ELSE mdio_write1(0x1F, 0x0A42); s := mdio_read(0x16); s := s + {1}; mdio_write(0x16, s); END; mdio_write1(0x1F, 0x0000); END; END enable_EEE; PROCEDURE disable_EEE; VAR s: SET; BEGIN CASE hwCfgMethod OF |CFG_METHOD_11,CFG_METHOD_12,CFG_METHOD_13: eri_write(0x1B0, 2, {}, ERIAR_ExGMAC); mdio_write1(0x1F, 0x0004); mdio_write1(0x10, 0x401F); mdio_write1(0x19, 0x7030); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0007); mdio_write1(0x0E, 0x003C); mdio_write1(0x0D, 0x4007); mdio_write1(0x0E, 0x0000); mdio_write1(0x0D, 0x0000); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0003); mdio_write1(0x0E, 0x0015); mdio_write1(0x0D, 0x4003); mdio_write1(0x0E, 0x0000); mdio_write1(0x0D, 0x0000); mdio_write(NetworkMii.BMCR,NetworkMii.BMCR_AutoNegotiationEnable+NetworkMii.BMCR_RestartAutoNegotiation); |CFG_METHOD_14: eri_write(0x1B0, 2, {}, ERIAR_ExGMAC); mdio_write1(0x1F, 0x0004); mdio_write1(0x10, 0x401F); mdio_write1(0x19, 0x7030); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0007); mdio_write1(0x0E, 0x003C); mdio_write1(0x0D, 0x4007); mdio_write1(0x0E, 0x0000); mdio_write1(0x0D, 0x0000); mdio_write(NetworkMii.BMCR, NetworkMii.BMCR_AutoNegotiationEnable+NetworkMii.BMCR_RestartAutoNegotiation); |CFG_METHOD_15,CFG_METHOD_16: eri_write(0x1B0, 2, {}, ERIAR_ExGMAC); mdio_write1(0x1F, 0x0004); mdio_write1(0x10, 0xC07F); mdio_write1(0x19, 0x7030); mdio_write1(0x1F, 0x0000); mdio_write1(0x1F, 0x0000); mdio_write1(0x0D, 0x0007); mdio_write1(0x0E, 0x003C); mdio_write1(0x0D, 0x4007); mdio_write1(0x0E, 0x0000); mdio_write1(0x0D, 0x0000); mdio_write(NetworkMii.BMCR, NetworkMii.BMCR_AutoNegotiationEnable+NetworkMii.BMCR_RestartAutoNegotiation); |CFG_METHOD_17: s := eri_read(0x1B0, 4, ERIAR_ExGMAC); s := s - {0,1}; eri_write(0x1B0, 4, s, ERIAR_ExGMAC); mdio_write1(0x1F, 0x0A43); s := mdio_read( 0x11); mdio_write(0x11, s - {4}); mdio_write1(0x1F, 0x0A5D); mdio_write1(0x10, 0x0000); mdio_write1(0x1F, 0x0000); ELSE TRACE("No EEE support!"); RETURN; END; (*Advanced EEE*) IF hwCfgMethod = CFG_METHOD_17 THEN eri_write(0x1EA, 1, {}, ERIAR_ExGMAC); mdio_write1(0x1F, 0x0A42); s := mdio_read( 0x16); s := s - {1}; mdio_write(0x16, s); mdio_write1(0x1F, 0x0000); END; END disable_EEE; PROCEDURE hw_phy_config; VAR s: SET; BEGIN xmii_reset_enable; init_hw_phy_mcu; IF hwCfgMethod = CFG_METHOD_4 THEN mdio_write1(0x1f, 0x0000); mdio_write(0x11, mdio_read(0x11) + S.VAL(SET,0x1000)); mdio_write(0x19, mdio_read(0x19) + S.VAL(SET,0x2000)); mdio_write(0x10, mdio_read(0x10) + S.VAL(SET,0x8000)); mdio_write1(0x1f, 0x0003); mdio_write1(0x08, 0x441D); mdio_write1(0x01, 0x9100); mdio_write1(0x1f, 0x0000); ELSIF hwCfgMethod = CFG_METHOD_5 THEN mdio_write1(0x1f, 0x0000); mdio_write(0x11, mdio_read(0x11) + S.VAL(SET,0x1000)); mdio_write(0x19, mdio_read(0x19) + S.VAL(SET,0x2000)); mdio_write(0x10, mdio_read(0x10) + S.VAL(SET,0x8000)); mdio_write1(0x1f, 0x0003); mdio_write1(0x08, 0x441D); mdio_write1(0x01, 0x9100); mdio_write1(0x1f, 0x0000); ELSIF hwCfgMethod = CFG_METHOD_6 THEN mdio_write1(0x1f, 0x0000); mdio_write(0x11, mdio_read(0x11) + S.VAL(SET,0x1000)); mdio_write(0x19, mdio_read(0x19) + S.VAL(SET,0x2000)); mdio_write(0x10, mdio_read(0x10) + S.VAL(SET,0x8000)); mdio_write1(0x1f, 0x0003); mdio_write1(0x08, 0x441D); mdio_write1(0x1f, 0x0000); ELSIF (hwCfgMethod = CFG_METHOD_7) OR (hwCfgMethod = CFG_METHOD_8) THEN mdio_write1(0x1f, 0x0000); mdio_write(0x11, mdio_read(0x11) + S.VAL(SET,0x1000)); mdio_write(0x19, mdio_read(0x19) + S.VAL(SET,0x2000)); mdio_write(0x10, mdio_read(0x10) + S.VAL(SET,0x8000)); ELSIF hwCfgMethod = CFG_METHOD_9 THEN mdio_write1(0x1F, 0x0000); mdio_write(0x11, mdio_read(0x11) + {12}); mdio_write1(0x1F, 0x0002); mdio_write(0x0F, mdio_read(0x0F) + {0,1}); mdio_write1(0x1F, 0x0000); mdio_write1(0x1F, 0x0000); phyio_write(0x0E, S.VAL(SET,0x0068)); phyio_write(0x0E, S.VAL(SET,0x0069)); phyio_write(0x0E, S.VAL(SET,0x006A)); phyio_write(0x0E, S.VAL(SET,0x006B)); phyio_write(0x0E, S.VAL(SET,0x006C)); ELSIF hwCfgMethod = CFG_METHOD_10 THEN mdio_write1(0x1F, 0x0007); mdio_write1(0x1E, 0x0023); mdio_write1(0x17, 0x0116); mdio_write1(0x1F, 0x0000); mdio_write1(0x1f, 0x0005); mdio_write1(0x05, 0x8b80); mdio_write1(0x06, 0xc896); mdio_write1(0x1f, 0x0000); mdio_write1(0x1F, 0x0001); mdio_write1(0x0B, 0x8C60); mdio_write1(0x07, 0x2872); mdio_write1(0x1C, 0xEFFF); mdio_write1(0x1F, 0x0003); mdio_write1(0x14, 0x94B0); mdio_write1(0x1F, 0x0000); mdio_write1(0x1F, 0x0002); s := mdio_read(0x08) * S.VAL(SET,0x00FF); mdio_write(0x08, s + S.VAL(SET,0x8000)); mdio_write1(0x1F, 0x0007); mdio_write1(0x1E, 0x002D); s := mdio_read(0x18); mdio_write(0x18, s + S.VAL(SET,0x0010)); mdio_write1(0x1F, 0x0000); s := mdio_read(0x14); mdio_write(0x14, s + S.VAL(SET,0x8000)); mdio_write1(0x1F, 0x0002); mdio_write1(0x00, 0x080B); mdio_write1(0x0B, 0x09D7); mdio_write1(0x1f, 0x0000); mdio_write1(0x15, 0x1006); mdio_write1(0x1F, 0x0003); mdio_write1(0x19, 0x7F46); mdio_write1(0x1F, 0x0005); mdio_write1(0x05, 0x8AD2); mdio_write1(0x06, 0x6810); mdio_write1(0x05, 0x8AD4); mdio_write1(0x06, 0x8002); mdio_write1(0x05, 0x8ADE); mdio_write1(0x06, 0x8025); mdio_write1(0x1F, 0x0000); ELSIF (hwCfgMethod = CFG_METHOD_11) OR (hwCfgMethod = CFG_METHOD_12) OR (hwCfgMethod = CFG_METHOD_13) THEN IF Read8(0xEF) * S.VAL(SET,0x08) # {} THEN mdio_write1(0x1F, 0x0005); mdio_write1(0x1A, 0x0004); mdio_write1(0x1F, 0x0000); ELSE mdio_write1(0x1F, 0x0005); mdio_write1(0x1A, 0x0000); mdio_write1(0x1F, 0x0000); END; IF Read8(0xEF) * S.VAL(SET,0x010) # {} THEN mdio_write1(0x1F, 0x0004); mdio_write1(0x1C, 0x0000); mdio_write1(0x1F, 0x0000); ELSE mdio_write1(0x1F, 0x0004); mdio_write1(0x1C, 0x0200); mdio_write1(0x1F, 0x0000); END; mdio_write1(0x1F, 0x0001); mdio_write1(0x15, 0x7701); mdio_write1(0x1F, 0x0000); mdio_write1(0x1F, 0x0000); s := mdio_read(0x1A); mdio_write(0x08, s - {14}); IF ASPM THEN mdio_write1(0x1F, 0x0000); mdio_write1(0x18, 0x8310); mdio_write1(0x1F, 0x0000); END; ELSIF hwCfgMethod = CFG_METHOD_14 THEN IF ASPM THEN mdio_write1(0x1F, 0x0000); mdio_write1(0x18, 0x8310); mdio_write1(0x1F, 0x0000); END; ELSIF (hwCfgMethod = CFG_METHOD_15) OR (hwCfgMethod = CFG_METHOD_16) THEN mdio_write1(0x1F, 0x0001); mdio_write1(0x11, 0x83BA); mdio_write1(0x1F, 0x0000); IF ASPM THEN mdio_write1(0x1F, 0x0000); mdio_write1(0x18, 0x8310); mdio_write1(0x1F, 0x0000); END; ELSIF hwCfgMethod = CFG_METHOD_17 THEN mdio_write1(0x1F, 0x0BCC); mdio_write(0x14, mdio_read(0x14) - {8}); mdio_write1(0x1F, 0x0A44); mdio_write(0x11, mdio_read(0x11) + {7}); mdio_write(0x11, mdio_read(0x11) + {6}); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x8084); mdio_write(0x14, mdio_read(0x14) - {13,14}); mdio_write(0x10, mdio_read(0x10) + {12}); mdio_write(0x10, mdio_read(0x10) + {1}); mdio_write(0x10, mdio_read(0x10) + {0}); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x8012); mdio_write(0x14, mdio_read(0x14) + {15}); mdio_write1(0x1F, 0x0BCE); mdio_write1(0x12, 0x8860); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x80F3); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x8B00)); mdio_write1(0x13, 0x80F0); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x3A00)); mdio_write1(0x13, 0x80EF); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x0500)); mdio_write1(0x13, 0x80F6); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x6E00)); mdio_write1(0x13, 0x80EC); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x6800)); mdio_write1(0x13, 0x80ED); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x7C00)); mdio_write1(0x13, 0x80F2); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0xF400)); mdio_write1(0x13, 0x80F4); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x8500)); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x8110); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0xA800)); mdio_write1(0x13, 0x810F); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x1D00)); mdio_write1(0x13, 0x8111); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0xF500)); mdio_write1(0x13, 0x8113); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x6100)); mdio_write1(0x13, 0x8115); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x9200)); mdio_write1(0x13, 0x810E); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x0400)); mdio_write1(0x13, 0x810C); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x7C00)); mdio_write1(0x13, 0x810B); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x5A00)); mdio_write1(0x1F, 0x0A43); mdio_write1(0x13, 0x80D1); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0xFF00)); mdio_write1(0x13, 0x80CD); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x9E00)); mdio_write1(0x13, 0x80D3); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x0E00)); mdio_write1(0x13, 0x80D5); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0xCA00)); mdio_write1(0x13, 0x80D7); mdio_write(0x14, (mdio_read(0x14) - S.VAL(SET,0xFF00)) + S.VAL(SET,0x8400)); IF ASPM THEN IF hwHasWrRamCodeToMicroP THEN mdio_write1(0x1F, 0x0A43); mdio_write(0x10, mdio_read(0x10) + {2}); END; END; END; (*ocp phy power saving*) IF hwCfgMethod = CFG_METHOD_17 THEN IF ASPM THEN mdio_write1(0x1F, 0x0C41); mdio_write1(0x13, 0x0000); mdio_write1(0x13, 0x0050); mdio_write1(0x1F, 0x0000); END; END; mdio_write1(0x1F, 0x0000); IF hwHasWrRamCodeToMicroP THEN IF eee_enable THEN enable_EEE() ELSE disable_EEE(); END; END; END hw_phy_config; PROCEDURE set_speed_xmii(autoneg: BOOLEAN; speed: LONGINT; duplexFull: BOOLEAN); VAR auto_nego: SET; BEGIN IF (speed # SPEED_100) & (speed # SPEED_10) THEN speed := SPEED_100; duplexFull := TRUE; END; auto_nego := mdio_read(NetworkMii.ANAR); auto_nego := auto_nego - (NetworkMii.ANAR_10BaseTHalfDuplex+NetworkMii.ANAR_10BaseTFullDuplex+NetworkMii.ANAR_100BaseTXHalfDuplex+NetworkMii.ANAR_100BaseTXFullDuplex+NetworkMii.ANAR_Pause+NetworkMii.ANAR_AsymmetricPause); IF autoneg THEN IF speed = SPEED_10 THEN IF duplexFull THEN auto_nego := auto_nego + NetworkMii.ANAR_10BaseTHalfDuplex+NetworkMii.ANAR_10BaseTFullDuplex; ELSE auto_nego := auto_nego + NetworkMii.ANAR_10BaseTHalfDuplex; END; ELSE (* speed = SPEED_100 *) IF duplexFull THEN auto_nego := auto_nego + NetworkMii.ANAR_100BaseTXHalfDuplex+NetworkMii.ANAR_100BaseTXFullDuplex+NetworkMii.ANAR_10BaseTHalfDuplex+NetworkMii.ANAR_10BaseTFullDuplex; ELSE auto_nego := auto_nego + NetworkMii.ANAR_100BaseTXHalfDuplex+NetworkMii.ANAR_10BaseTHalfDuplex+NetworkMii.ANAR_10BaseTFullDuplex; END; END; (* flow contorol *) auto_nego := auto_nego + NetworkMii.ANAR_Pause+NetworkMii.ANAR_AsymmetricPause; IF (hwCfgMethod = CFG_METHOD_4) OR (hwCfgMethod = CFG_METHOD_5) OR (hwCfgMethod = CFG_METHOD_6) OR (hwCfgMethod = CFG_METHOD_7) OR (hwCfgMethod = CFG_METHOD_8) OR (hwCfgMethod = CFG_METHOD_9) THEN auto_nego := auto_nego - (NetworkMii.ANAR_Pause+NetworkMii.ANAR_AsymmetricPause); END; IF (hwCfgMethod = CFG_METHOD_10) OR (hwCfgMethod = CFG_METHOD_11) OR (hwCfgMethod = CFG_METHOD_12) OR (hwCfgMethod = CFG_METHOD_13) OR (hwCfgMethod = CFG_METHOD_14) OR (hwCfgMethod = CFG_METHOD_15) OR (hwCfgMethod = CFG_METHOD_16) THEN IF eee_enable THEN auto_nego := auto_nego - (NetworkMii.ANAR_Pause+NetworkMii.ANAR_AsymmetricPause); END; END; phy_auto_nego_reg := auto_nego; IF (hwCfgMethod = CFG_METHOD_4) OR (hwCfgMethod = CFG_METHOD_5) THEN mdio_write(0x1f,{}); mdio_write(NetworkMii.BMCR,NetworkMii.BMCR_Reset); Delay(1); hw_phy_config; ELSIF ((hwCfgMethod = CFG_METHOD_1) OR (hwCfgMethod = CFG_METHOD_2) OR (hwCfgMethod = CFG_METHOD_3)) & (speed = SPEED_10) THEN mdio_write(0x1f,{}); mdio_write(NetworkMii.BMCR,NetworkMii.BMCR_Reset); hw_phy_config; END; ELSE HALT(100); (*! not implemented *) END; END set_speed_xmii; PROCEDURE xmii_link_ok(): BOOLEAN; BEGIN RETURN Read8(PHYstatus) * LinkStatus # {}; END xmii_link_ok; PROCEDURE enable_rxdvgate; BEGIN IF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) END; END enable_rxdvgate; PROCEDURE wait_txrx_fifo_empty; BEGIN IF hwCfgMethod = CFG_METHOD_17 THEN HALT(100); (*! Not implemented *) END; END wait_txrx_fifo_empty; PROCEDURE nic_reset; VAR i: LONGINT; BEGIN Write32(RxConfig,S.VAL(SET,LSH(RX_DMA_BURST,RxCfgDMAShift))); enable_rxdvgate; wait_txrx_fifo_empty; CASE hwCfgMethod OF |CFG_METHOD_1,CFG_METHOD_2,CFG_METHOD_3: Write8(ChipCmd, StopReq + CmdRxEnb + CmdTxEnb); Delay(1); |CFG_METHOD_14: |CFG_METHOD_17: Delay(2); ELSE Delay(10); END; (* Soft reset the chip. *) Write8(ChipCmd, CmdReset); (* Check that the chip has finished the reset. *) i := 0; WHILE (i < 100) & (Read8(ChipCmd) * CmdReset # {}) DO Delay(1); INC(i); END; ASSERT(i < 100); END nic_reset; PROCEDURE AllocBuffer(VAR buf: TxBuffer); BEGIN NEW(buf); (* edit: no more alignment necessary, since PTR TO RECORD is already 32 byte aligned *) END AllocBuffer; PROCEDURE SetupRxRing(): Machine.Address32; VAR r: LONGINT; adr, physAdr: ADDRESS; buf, prev: RxBuffer; BEGIN (* make sure the descriptor ring is 256 byte aligned in physical memory *) adr := ADDRESSOF(rdsBuf[0]); physAdr := Machine.PhysicalAdr(adr, LEN(rdsBuf,0)); TRACE(adr,physAdr); r := physAdr MOD 256; IF r # 0 THEN r := 256-r; END; TRACE(r); INC(adr,r); TRACE(adr); FOR r := 0 TO RxRingSize - 1 DO rds[r] := adr; INC(adr,SizeOfRxTxFDHdr); END; firstRD := 0; IF DebugRxRing IN Debug THEN KernelLog.String("Rx descriptor start = "); KernelLog.Hex(ADDRESSOF(rds[firstRD]^), 8); KernelLog.Ln; KernelLog.String("first Rx descriptor id = "); KernelLog.Int(firstRD, 0); KernelLog.Ln; END; FOR r := firstRD TO RxRingSize - 1 DO NEW(buf); buf.buf := Network.GetNewBuffer(); ASSERT(buf.buf # NIL); adr := ADDRESSOF(buf.buf.data[0]); physAdr := Machine.PhysicalAdr(adr, Network.MaxPacketSize); ASSERT(physAdr # Machine.NilAdr); rds[r].flags := {31} + (S.VAL(SET, Network.MaxPacketSize) * {0..13}); rds[r].vLanTag := 0; rds[r].bufAdrLo := Machine.Ensure32BitAddress (physAdr); rds[r].bufAdrHi := 0; IF prev # NIL THEN prev.next := buf; ELSE (* set first Rx Buffer *) rxBuffer := buf; END; prev := buf; END; rxLast := buf; rxLast.next := rxBuffer; (* mark last descriptor as EOR (end of descriptor ring) *) INCL(rds[RxRingSize - 1].flags, 30); curRD := firstRD; adr := ADDRESSOF(rds[firstRD]^); (* return physical address of first rx descriptor *) RETURN Machine.Ensure32BitAddress (Machine.PhysicalAdr(adr, SizeOfRxTxFDHdr)); END SetupRxRing; PROCEDURE SetupTxRing(): Machine.Address32; VAR r: LONGINT; adr, physAdr: ADDRESS; buf, prev: TxBuffer; BEGIN (* make sure the descriptor ring is 256 byte aligned in physical memory *) adr := ADDRESSOF(tdsBuf[0]); physAdr := Machine.PhysicalAdr(adr, LEN(tdsBuf,0)); TRACE(adr,physAdr); r := physAdr MOD 256; IF r # 0 THEN r := 256-r; END; TRACE(r); INC(adr,r); TRACE(adr); FOR r := 0 TO TxRingSize - 1 DO tds[r] := adr; INC(adr,SizeOfRxTxFDHdr); END; firstTD := 0; lastTD := firstTD; nofFreeTx := TxRingSize - firstTD; IF DebugTxRing IN Debug THEN KernelLog.String("Tx descriptor start = "); KernelLog.Hex(ADDRESSOF(tds[firstTD]^), -8); KernelLog.Ln; KernelLog.String("first Tx descriptor id = "); KernelLog.Int(firstTD, 0); KernelLog.Ln; KernelLog.String("nofFreeTx = "); KernelLog.Int(nofFreeTx, 0); KernelLog.Ln; END; FOR r := firstTD TO TxRingSize - 1 DO AllocBuffer(buf); (* configure TFD *) adr := ADDRESSOF(buf.data[0]); physAdr := Machine.PhysicalAdr(adr, TxBufMaxSize); ASSERT(physAdr # Machine.NilAdr); tds[r].flags := {}; tds[r].vLanTag := 0; tds[r].bufAdrLo := Machine.Ensure32BitAddress (physAdr); tds[r].bufAdrHi := 0; IF prev # NIL THEN prev.next := buf; ELSE (* set first Tx Buffer *) txBuffer := buf; END; prev := buf; END; txLast := buf; txLast.next := txBuffer; (* mark last descriptor as EOR (end of descriptor ring) *) INCL(tds[TxRingSize - 1].flags, 30); curTD := firstTD; adr := ADDRESSOF(tds[firstTD]^); (* return physical address of first tx descriptor *) RETURN Machine.Ensure32BitAddress (Machine.PhysicalAdr(adr, SizeOfRxTxFDHdr)); END SetupTxRing; PROCEDURE SendFrame(dst: Network.LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT); VAR txLen, offset, type4: LONGINT; bufBase: ADDRESS; chksums: SET; BEGIN {EXCLUSIVE} IF nofFreeTx <= 0 THEN KernelLog.String("no tx buffers"); KernelLog.Ln; INC(nTxOverflow); END; AWAIT(nofFreeTx > 0); txLen := 14 + h3len + h4len + dlen; bufBase := ADDRESSOF(txBuffer.data); (* generate ethernet frame: setup eth header, move data *) (* set destination mac address (first 6 bytes of eth frame) *) S.MOVE(ADDRESSOF(dst[0]), bufBase, 6); (* set source mac address (6 bytes @ offset 6 of eth frame) *) S.MOVE(ADDRESSOF(dev.local[0]), bufBase + 6, 6); (* set upper layer type, bring type from host to network byte order *) S.PUT16(bufBase + 12, ROT(S.VAL(INTEGER, SHORT(type)), 8)); offset := 14; (* eth header has 14 bytes *) (* move layer 3 and layer 4 headers, data *) IF h3len > 0 THEN S.MOVE(ADDRESSOF(l3hdr[0]), bufBase + offset, h3len); INC(offset, h3len); END; IF h4len > 0 THEN S.MOVE(ADDRESSOF(l4hdr[0]), bufBase + offset, h4len); INC(offset, h4len); END; IF offset + dlen < MaxETHFrameSize THEN S.MOVE(ADDRESSOF(data[0]) + dofs, bufBase + offset, dlen); INC(offset, dlen); END; (* make the frame at least 64 bytes long *) WHILE offset < 60 DO txBuffer.data[offset] := CHR(0); INC(offset); INC(txLen); END; IF DebugTransmit IN Debug THEN KernelLog.String("Sending frame of length "); KernelLog.Int(txLen, 0); KernelLog.Ln;  (*KernelLog.Memory(bufBase, txLen);*) END; (* find out which protocols are used; let the NIC calc the checksums for IP, TCP and UCP headers *) chksums := {}; IF type = 0800H THEN INCL(chksums, 29(*18*)); (* offload IP checksum *) type4 := S.VAL(SHORTINT, l3hdr[9]); (* get type if IP data *) IF type4 = 6 THEN (* TCP/IP *) INCL(chksums, 30(*16*)); (* offload TCP checksum *) ELSIF type4 = 17 THEN INCL(chksums, 31(*17*)); (* offload UDP checksum *) END; END; (* update Tx Descriptor: set OWN=1, FS=1, LS=1, checksum offloads; set size of packet to be transmitted *) tds[curTD].flags := tds[curTD].flags * {30}; (* only keep EOR bit *) tds[curTD].flags := tds[curTD].flags + {31, 29, 28} (*+ chksums*); tds[curTD].flags := tds[curTD].flags + (S.VAL(SET, txLen) * {0..15}); tds[curTD].vLanTag := S.VAL(LONGINT,chksums); (* move to next Tx Descriptor, Tx Buffer *) INC(curTD); IF curTD = TxRingSize THEN curTD := firstTD; END; txBuffer := txBuffer.next; DEC(nofFreeTx); (* tell the nic that there's some eth frame waiting to be transmitted (set NPQ=1) *) Write8(38H,{6}); END SendFrame; PROCEDURE Read8(reg: LONGINT): SET; BEGIN RETURN S.VAL(SET,LONGINT(S.GET8(base+reg))); END Read8; PROCEDURE Write8(reg: LONGINT; val: SET); BEGIN S.PUT8(base+reg,SHORTINT(S.VAL(LONGINT,val))); (*KernelLog.String("W8 0x"); KernelLog.Hex(reg,-2); KernelLog.String(" 0x"); KernelLog.Hex(S.VAL(LONGINT,val),-2); KernelLog.Ln;*) END Write8; PROCEDURE Read16(reg: LONGINT): SET; BEGIN RETURN S.VAL(SET,LONGINT(S.GET16(base+reg))); END Read16; PROCEDURE Write16(reg: LONGINT; val: SET); BEGIN S.PUT16(base+reg,INTEGER(S.VAL(LONGINT,val))); (*KernelLog.String("W16 0x"); KernelLog.Hex(reg,-2); KernelLog.String(" 0x"); KernelLog.Hex(S.VAL(LONGINT,val),-4); KernelLog.Ln;*) END Write16; PROCEDURE Read32(reg: LONGINT): SET; BEGIN RETURN S.VAL(SET,S.GET32(base+reg)); END Read32; PROCEDURE Write32(reg: LONGINT; val: SET); BEGIN S.PUT32(base+reg,val); (*KernelLog.String("W32 0x"); KernelLog.Hex(reg,-2); KernelLog.String(" 0x"); KernelLog.Hex(S.VAL(LONGINT,val),-8); KernelLog.Ln;*) END Write32; PROCEDURE UpdateLinkStatus; BEGIN IF xmii_link_ok() THEN linkStatus := Network.LinkLinked; ELSE linkStatus := Network.LinkNotLinked; END; END UpdateLinkStatus; PROCEDURE CheckChecksumErrors(d: RxTxDescriptor): BOOLEAN; VAR proto: SET; BEGIN proto := d.flags * {17..18}; IF proto = {} THEN RETURN TRUE; (* no checksum errors since non-ip packet *) ELSIF proto = {17} THEN (* protocol is TCP/IP so check IP and TCP checksum failures *) RETURN d.flags * {14, 16} = {}; ELSIF proto = {18} THEN (* protocol is UDP/IP so check IP and UDP checksum failures *) RETURN d.flags * {15, 16} = {}; ELSE (* protocol is IP so check IP checksum failures *) RETURN d.flags * {16} = {}; END; END CheckChecksumErrors; PROCEDURE ReadFrames; VAR adr: ADDRESS; type, size: LONGINT; dstAdr: Network.LinkAdr; buf: Network.Buffer; s: SET; BEGIN (* read all frames that are marked with OWN = 0*) WHILE ~(31 IN rds[curRD].flags) DO (* skip error frames *) IF (21 IN rds[curRD].flags) THEN INC(nRxErrorFrames); ELSIF CheckChecksumErrors(rds[curRD]^) THEN (* find out how many bytes have been received, including CRC *) size := S.VAL(LONGINT, rds[curRD].flags * {0..13}); IF DebugReceive IN Debug THEN KernelLog.String("Received a frame of length "); KernelLog.Int(size, 0); KernelLog.Ln; END; adr := ADDRESSOF(rxBuffer.buf.data[0]); (* copy destination and source addresses, type of packet *) dstAdr := S.VAL(Network.LinkAdr, rxBuffer.buf.data[0]); rxBuffer.buf.src := S.VAL(Network.LinkAdr, rxBuffer.buf.data[6]); type := Network.GetNet2(rxBuffer.buf.data, 12); buf := rxBuffer.buf; buf.ofs := 14; buf.len := size - 14; buf.calcChecksum := { Network.ChecksumIP, Network.ChecksumUDP, Network.ChecksumTCP }; buf.next := NIL; buf.prev := NIL; IF type = 0DEADH THEN (* make sure the frame doesn't bounce between the two cards by adding 1 to the type *) SendFrame(buf.src, type + 1, buf.data, buf.data, buf.data, 0, 0, 0, buf.len); ELSIF type = 0DEADH + 1 THEN (* discard this frame *) ELSE dev.QueueBuffer(buf, type); END; INC(nRxFrames); IF (type # 0DEADH) & (type # 0DEADH + 1) THEN rxBuffer.buf := Network.GetNewBuffer(); buf := rxBuffer.buf; ASSERT(rxBuffer.buf # NIL); IF buf # NIL THEN rds[curRD].bufAdrLo := Machine.Ensure32BitAddress (Machine.PhysicalAdr(ADDRESSOF(rxBuffer.buf.data[0]), Network.MaxPacketSize)); END; END; ELSE IF DebugReceive IN Debug THEN IF 16 IN rds[curRD].flags THEN KernelLog.String("IP "); ELSIF 15 IN rds[curRD].flags THEN KernelLog.String("UDP "); ELSIF 14 IN rds[curRD].flags THEN KernelLog.String("TCP "); END; KernelLog.String("checksum error detected!"); KernelLog.Ln; END; INC(nRxErrorFrames); END; (* mark the buffer to be able to receive again *) rds[curRD].flags := {31} + (rds[curRD].flags * {30}) + (S.VAL(SET, Network.MaxPacketSize) * {0..13}); rds[curRD].vLanTag := 0; s := rds[curRD].flags; (* advance Rx descriptor, Rx buffer *) rxBuffer := rxBuffer.next; INC(curRD); IF curRD = RxRingSize THEN curRD := firstRD; END; END; END ReadFrames; PROCEDURE UpdateTxRing; VAR i: LONGINT; BEGIN { EXCLUSIVE } i := lastTD; WHILE (i # curTD) DO IF DebugTransmit IN Debug THEN KernelLog.String("*** Tx OK ***"); KernelLog.Ln; END; INC(i); INC(nTxFrames); INC(nofFreeTx); IF i = TxRingSize THEN i := firstTD; END; txLast := txLast.next; END; lastTD := i; END UpdateTxRing; PROCEDURE HandleInterrupt; VAR status: SET; BEGIN status := Read16(IntrStatus); Write16(IntrMask,{}); (* System Error *) IF (SYSErr IN intr_mask) & (SYSErr IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("System Error Interrupt"); KernelLog.Ln; END; END; (* Time Out (TimeOut) *) IF (PCSTimeout IN intr_mask) & (PCSTimeout IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Timeout Interrupt"); KernelLog.Ln; END; END; IF (SWInt IN intr_mask) & (SWInt IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Software Interrupt"); KernelLog.Ln; END; END; IF (TxDescUnavail IN intr_mask) & (TxDescUnavail IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Tx Descriptor Unavailable Interrupt"); KernelLog.Ln; END; (*UpdateTxRing;*) (*INCL(status, 2); (* let the tx ring be updated *)*) END; (* Rx FIFO Overflow *) IF (RxFIFOOver IN intr_mask) & (RxFIFOOver IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Rx FIFO Overflow Interrupt"); KernelLog.Ln; END; INC(nRxOverflow); (*INCL(ack, 4);*) (*INCL(status, 0); (* read the frames *)*) END; (* Link Change *) IF (LinkChg IN intr_mask) & (LinkChg IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Link Change Interrupt"); KernelLog.Ln; END; UpdateLinkStatus; END; (* Rx Descriptor Unavailable *) IF (RxDescUnavail IN intr_mask) & (RxDescUnavail IN status) THEN IF DebugInterrupt IN Debug THEN (* CAREFUL: UN-COMMENTING THE NEXT LINE CAN CRASH THE OS *) KernelLog.String("Rx Descriptor Unavailable Interrupt"); KernelLog.Ln; END; (*INCL(status, 0); (* read the frames *)*) END; (* Transmit Error *) IF (TxErr IN intr_mask) & (TxErr IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Transmit Error Interrupt"); KernelLog.Ln; END; INC(nTxErrorFrames); INCL(status, TxErr); (* let the tx ring be updated *) END; (* Transmit OK *) IF (TxOK IN intr_mask) & (TxOK IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Transmit OK Interrupt"); KernelLog.Ln; END; UpdateTxRing; END; (* Receive Error *) IF (RxErr IN intr_mask) & (RxErr IN status) THEN IF DebugInterrupt IN Debug THEN KernelLog.String("Receive Error Interrupt"); KernelLog.Ln; END; (*ReadFrames;*) INCL(status, RxErr); (* let the rx ring be updated *) END; (* Receive OK *) IF (RxOK IN intr_mask) & (RxOK IN status) THEN IF DebugInterrupt IN Debug THEN (* CAREFUL: UN-COMMENTING THE NEXT LINE CAN CRASH THE OS *) KernelLog.String("Receive Ok Interrupt"); KernelLog.Ln; END; ReadFrames; END; Write16(IntrStatus,status); Write16(IntrMask,intr_mask); END HandleInterrupt; PROCEDURE Finalize; VAR s: SET; BEGIN (* cleanup Network registry *) Network.registry.Remove(dev); (* disable Tx and Rx *) s := S.VAL(SET, Read8(37H)); Write8(37H,s - {2, 3}); (* soft reset *) Write8(37H,{4}); (* disable all interrupts *) Write16(3CH, {}); WHILE (rxBuffer # NIL) & (rxBuffer.buf # NIL) DO Network.ReturnBuffer(rxBuffer.buf); rxBuffer.buf := NIL; rxBuffer := rxBuffer.next; END; IF DebugCleanup IN Debug THEN KernelLog.String("Removing IRQ Handler."); KernelLog.Ln END; Objects.RemoveHandler(SELF.HandleInterrupt, Machine.IRQ0 + irq); END Finalize; PROCEDURE DebugConfig; VAR s: SET; res: LONGINT; BEGIN KernelLog.String("*** BEGIN OF NIC CONFIGURATION ***"); KernelLog.Ln; s := Read16(0E0H); KernelLog.String("C+ Command:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Set(s); KernelLog.Ln; KernelLog.String("Rx Descriptor base address:"); KernelLog.Ln; KernelLog.String(" "); res := S.VAL(LONGINT,Read32(0E4H + 4H)); KernelLog.Hex(res, 8); res := S.VAL(LONGINT,Read32(0E4H)); KernelLog.Hex(res, 8); KernelLog.Ln; KernelLog.String("Tx Normal Priority Descriptor base address:"); KernelLog.Ln; KernelLog.String(" "); res := S.VAL(LONGINT,Read32(020H + 4H)); KernelLog.Hex(res, 8); res := S.VAL(LONGINT,Read32(020H)); KernelLog.Hex(res, 8); KernelLog.Ln; res := S.VAL(LONGINT,Read16(0DAH)); KernelLog.String("Receive Packet Max Size:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Int(res, 0); KernelLog.Ln; res := S.VAL(LONGINT,Read8(0ECH)); KernelLog.String("Max Transmit Packet Size:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Int(res * 128, 0); KernelLog.Ln; s := Read32(40H); KernelLog.String("Transmit Configuration:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Set(s); KernelLog.Ln; s := Read32(44H); KernelLog.String("Receive Configuration:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Set(s); KernelLog.Ln; s := Read16(3CH); KernelLog.String("interrupt mask:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Set(s); KernelLog.Ln; s := Read8(37H); KernelLog.String("command bits:"); KernelLog.Ln; KernelLog.String(" "); KernelLog.Set(s); KernelLog.Ln; KernelLog.String("*** END OF NIC CONFIGURATION ***"); KernelLog.Ln; END DebugConfig; PROCEDURE PrintStatus; VAR phyStatus: SET; BEGIN phyStatus := S.VAL(SET, Read8(6CH)); IF 1 IN phyStatus THEN KernelLog.String(" Device is linked"); KernelLog.Ln; IF 3 IN phyStatus THEN KernelLog.String(" Linkspeed is 100Mbps"); KernelLog.Ln; ELSE TRACE(2 IN phyStatus); KernelLog.String(" Linkspeed is 10MBps"); KernelLog.Ln; END; IF 0 IN phyStatus THEN KernelLog.String(" Device is in Full-Duplex mode"); KernelLog.Ln; ELSE KernelLog.String(" Device is in Half-Duplex mode"); KernelLog.Ln; END; ELSE KernelLog.String(" Device is NOT linked"); KernelLog.Ln; END; IF 6 IN phyStatus THEN KernelLog.String(" Transmit Flow Control enabled"); KernelLog.Ln; END; IF 5 IN phyStatus THEN KernelLog.String(" Receive Flow Control enabled"); KernelLog.Ln; END; KernelLog.String(" nRxOverflow = "); KernelLog.HIntHex(nRxOverflow, 16); KernelLog.Ln; KernelLog.String(" nTxOverflow = "); KernelLog.HIntHex(nTxOverflow, 16); KernelLog.Ln; (*KernelLog.String(" Rx Missed Packet Counter = "); KernelLog.Int(Read32(4CH), 0); KernelLog.Ln;*) KernelLog.String(" nRxFrames = "); KernelLog.Int(nRxFrames, 0); KernelLog.Ln; KernelLog.String(" nTxFrames = "); KernelLog.Int(nTxFrames, 0); KernelLog.Ln; KernelLog.String(" nRxErrorFrames = "); KernelLog.Int(nRxErrorFrames, 0); KernelLog.Ln; KernelLog.String(" nTxErrorFrames = "); KernelLog.Int(nTxErrorFrames, 0); KernelLog.Ln; END PrintStatus; END Controller; VAR installedControllers: Controller; (* software reset of the device *) PROCEDURE SoftReset(base: ADDRESS); VAR s: SET; BEGIN TRACE(ChipCmd,CmdReset); S.PUT8(base+ChipCmd,CmdReset); (* wait until reset has finished *) REPEAT Delay(1); s := S.VAL(SET,LONGINT(S.GET8(base+ChipCmd))); UNTIL s * CmdReset = {}; END SoftReset; PROCEDURE irq_mask_and_ack(base: ADDRESS); BEGIN S.PUT16(base+IntrMask,0); TRACE(IntrMask,IntrStatus,S.GET16(base+IntrStatus)); S.PUT16(base+IntrStatus,S.GET16(base+IntrStatus)); END irq_mask_and_ack; (* Get device name given the determined configuration method *) PROCEDURE GetDeviceName(hwCfgMethod: LONGINT; VAR name: ARRAY OF CHAR); BEGIN CASE hwCfgMethod OF |CFG_METHOD_1: name := "RTL8101E"; |CFG_METHOD_2: name := "RTL8101E"; |CFG_METHOD_3: name := "RTL8101E"; |CFG_METHOD_4: name := "RTL8102E"; |CFG_METHOD_5: name := "RTL8102E"; |CFG_METHOD_6: name := "RTL8103E"; |CFG_METHOD_7: name := "RTL8103E"; |CFG_METHOD_8: name := "RTL8103E"; |CFG_METHOD_9: name := "RTL8401"; |CFG_METHOD_10: name := "RTL8105E"; |CFG_METHOD_11: name := "RTL8105E"; |CFG_METHOD_12: name := "RTL8105E"; |CFG_METHOD_13: name := "RTL8105E"; |CFG_METHOD_14: name := "RTL8402"; |CFG_METHOD_15: name := "RTL8106E"; |CFG_METHOD_16: name := "RTL8106E"; |CFG_METHOD_17: name := "RTL8106EUS"; ELSE name := ""; END; END GetDeviceName; (* Identify device and the required configuration method *) PROCEDURE IdentifyDevice(base: ADDRESS; VAR hwCfgMethod: LONGINT; VAR hwIcVerUnknown: BOOLEAN; VAR chipsetInd: LONGINT; VAR hwName: ARRAY OF CHAR); VAR s: SET; v, id, i: LONGINT; BEGIN (*! disable interrupts ? *) irq_mask_and_ack(base); (* reset the device *) SoftReset(base); (* identify the device *) s := S.VAL(SET,S.GET32(base+40H)); v := S.VAL(LONGINT,s * {23,26..30}); id := S.VAL(LONGINT,s * {20..22}); hwCfgMethod := -1; hwName := ""; hwIcVerUnknown := FALSE; IF v = 0x34000000 THEN IF id = 0x00000000 THEN hwCfgMethod := CFG_METHOD_1; ELSIF id = 0x00200000 THEN hwCfgMethod := CFG_METHOD_2; ELSIF id = 0x00300000 THEN hwCfgMethod := CFG_METHOD_3; ELSE hwCfgMethod := CFG_METHOD_3; hwIcVerUnknown := TRUE; END; ELSIF (v = 0x34800000) OR (v = 0x24800000) THEN IF id = 0x00100000 THEN hwCfgMethod := CFG_METHOD_4; ELSIF id = 0x00200000 THEN hwCfgMethod := CFG_METHOD_5; ELSIF id = 0x00400000 THEN hwCfgMethod := CFG_METHOD_6; ELSIF id = 0x00500000 THEN hwCfgMethod := CFG_METHOD_7; ELSIF id = 0x00600000 THEN hwCfgMethod := CFG_METHOD_8; ELSE hwCfgMethod := CFG_METHOD_8; hwIcVerUnknown := TRUE; END; ELSIF v = 0x24000000 THEN hwCfgMethod := CFG_METHOD_9; ELSIF v = 0x2C000000 THEN IF (id = 0x00000000) OR (id = 0x00100000) OR (id = 0x00200000) THEN hwCfgMethod := CFG_METHOD_10; ELSE hwCfgMethod := CFG_METHOD_10; hwIcVerUnknown := TRUE; END; ELSIF v = 0x40800000 THEN IF id = 0x00100000 THEN hwCfgMethod := CFG_METHOD_11; ELSIF id = 0x00200000 THEN hwCfgMethod := CFG_METHOD_12; ELSIF id = 0x00300000 THEN hwCfgMethod := CFG_METHOD_13; ELSIF id = 0x00400000 THEN hwCfgMethod := CFG_METHOD_13; ELSE hwCfgMethod := CFG_METHOD_13; hwIcVerUnknown := TRUE; END; ELSIF v = 0x44000000 THEN hwCfgMethod := CFG_METHOD_14; ELSIF v = 0x44800000 THEN IF id = 0x00000000 THEN hwCfgMethod := CFG_METHOD_15; ELSIF id = 0x00100000 THEN hwCfgMethod := CFG_METHOD_16; ELSE hwCfgMethod := CFG_METHOD_16; hwIcVerUnknown := TRUE; END; ELSIF v = 0x50800000 THEN IF id = 0x00100000 THEN hwCfgMethod := CFG_METHOD_17; ELSE hwCfgMethod := CFG_METHOD_17; hwIcVerUnknown := TRUE; END; END; chipsetInd := 0; WHILE (chipsetInd < LEN(HwCfgMethods,0)) & (hwCfgMethod # HwCfgMethods[chipsetInd]) DO INC(chipsetInd); END; ASSERT(i < LEN(HwCfgMethods,0)); GetDeviceName(hwCfgMethod,hwName); IF DebugHWVer IN Debug THEN KernelLog.String("Hardware Version: "); IF hwName # "" THEN KernelLog.String(hwName); ELSE KernelLog.String("Hardware Version is unknown"); END; KernelLog.Ln; END; END IdentifyDevice; (* Scan the PCI bus for the specified card. *) PROCEDURE ScanPCI(vendor, device: LONGINT); VAR index, bus, dev, fct, res, irq, i: LONGINT; base: ADDRESS; d: LinkDevice; c: Controller; name: Plugins.Name; hwCfgMethod, chipsetInd: LONGINT; hwIcVerUnknown: BOOLEAN; hwName: ARRAY 256 OF CHAR; BEGIN index := 0; WHILE (PCI.FindPCIDevice(device, vendor, index, bus, dev, fct) = PCI.Done) & (installed < 16) DO res := PCI.ReadConfigDword(bus, dev, fct, PCI.Adr2Reg, i); ASSERT(res = PCI.Done); base := i; ASSERT(~ODD(base)); (* memory mapped *) DEC(base, base MOD 16); Machine.MapPhysical(base, 0FFH, base); IdentifyDevice(base,hwCfgMethod,hwIcVerUnknown,chipsetInd,hwName); IF hwCfgMethod # -1 THEN res := PCI.ReadConfigByte(bus, dev, fct, PCI.IntlReg, irq); ASSERT(res = PCI.Done); NEW(d, Network.TypeEthernet, MaxETHFrameSize - 14, 6); COPY(hwName,name); i := 0; WHILE name[i] # 0X DO INC(i) END; name[i] := "#"; INC(i); IF installed > 9 THEN name[i] := CHR(ORD("A") + installed - 10); ELSE name[i] := CHR(ORD("0") + installed); END; name[i+1] := 0X; IF DebugFind IN Debug THEN KernelLog.String("Found device: "); KernelLog.String(name); KernelLog.String("; IRQ = "); KernelLog.Int(irq, 0); KernelLog.Ln; END; d.SetName(name); d.desc := Description; NEW(c, d, base, irq, bus,dev,fct,hwCfgMethod,chipsetInd,hwIcVerUnknown); (* increments "installed" when successful *) IF DebugStatus IN Debug THEN c.PrintStatus; END; ELSE Machine.UnmapPhysical(base,0FFH); END; INC(index); END END ScanPCI; PROCEDURE Install*; BEGIN {EXCLUSIVE} IF DebugFind IN Debug THEN KernelLog.String("Searching devices..."); KernelLog.Ln END; IF installed = 0 THEN ScanPCI(10ECH, 8136H); (* Vendor = RealTek, Device = RTL8101E *) END; IF DebugFind IN Debug THEN KernelLog.String("Find finished."); KernelLog.Ln END; END Install; PROCEDURE DebugStati*; VAR c: Controller; BEGIN c := installedControllers; WHILE c # NIL DO c.PrintStatus; c := c.next; END; END DebugStati; PROCEDURE TestDevices*; VAR c: Controller; BEGIN c := installedControllers; WHILE c # NIL DO TestDevice(c); c := c.next; END; END TestDevices; PROCEDURE TestDevice(ctrl: Controller); VAR i, diff, bytes, times: LONGINT; milliTimer : Kernel.MilliTimer; data: ARRAY 1024 OF CHAR; bw: REAL; dst: Network.LinkAdr; BEGIN dst[0] := 000X; dst[1] := 030X; dst[2] := 04FX; dst[3] := 025X; dst[4] := 0BBX; dst[5] := 0DBX; IF ctrl # NIL THEN ctrl.nRxFrames := 0; ctrl.nTxFrames := 0; (* fill the buffer *) FOR i := 0 TO LEN(data)-1 DO data[i] := CHR(i MOD 100H) END; Kernel.SetTimer(milliTimer, 0); times := 1024; FOR i := 1 TO times DO ctrl.SendFrame(dst, 0DEADH, data, data, data, 0, 0, 0, LEN(data)); IF i MOD 1024 = 0 THEN Delay(1); END; END; diff := Kernel.Elapsed(milliTimer); times := ctrl.nRxFrames * 2; bytes := (LEN(data)); KernelLog.String("stats:"); KernelLog.Ln; KernelLog.String("frame size = "); KernelLog.Int(bytes, 0); KernelLog.String("; num frames = "); KernelLog.Int(times, 0); KernelLog.String("; time = "); KernelLog.Int(diff, 0); KernelLog.String("ms"); KernelLog.String("; bandwidth = "); bw := bytes * 1.0 * times / (diff / 1000.0); KernelLog.Int(ENTIER(bw / 1024), 0); KernelLog.String("KB/s, "); KernelLog.Int(ENTIER(bw * 8 / 1000 / 1000), 0); KernelLog.String("Mbps"); KernelLog.Ln; END END TestDevice; PROCEDURE Cleanup; BEGIN WHILE installedControllers # NIL DO IF DebugCleanup IN Debug THEN KernelLog.Ln; KernelLog.String("Removing "); KernelLog.String(installedControllers.dev.name); KernelLog.Ln; installedControllers.PrintStatus; END; installedControllers.Finalize; installedControllers := installedControllers.next; IF DebugCleanup IN Debug THEN KernelLog.String("Success!"); KernelLog.Ln; END; END; installedControllers := NIL; END Cleanup; PROCEDURE Delay(ms: LONGINT); VAR t: Kernel.MilliTimer; BEGIN Kernel.SetTimer(t, ms); REPEAT UNTIL Kernel.Expired(t); END Delay; VAR buf: ARRAY TxRingSize*SIZEOF(RxTxDescriptor)+256 OF CHAR; PROCEDURE TestAlloc*; VAR addr, physAddr: ADDRESS; dsc: ARRAY TxRingSize OF POINTER{UNSAFE,UNTRACED} TO RxTxDescriptor; r: LONGINT; BEGIN addr := ADDRESSOF(buf[0]); TRACE(addr); physAddr := Machine.PhysicalAdr(addr,LEN(buf,0)); TRACE(physAddr); r := physAddr MOD 256; TRACE(r); IF r # 0 THEN r := 256 - r; END; INC(addr,r); TRACE(addr); FOR r := 0 TO TxRingSize-1 DO dsc[r] := addr; INC(addr,SIZEOF(RxTxDescriptor)); dsc[r].flags := {31} + (S.VAL(SET, Network.MaxPacketSize) * {0..13}); dsc[r].vLanTag := 0; dsc[r].bufAdrLo := Machine.Ensure32BitAddress (physAddr); dsc[r].bufAdrHi := 0; END; TRACE(dsc[0],ADDRESSOF(dsc[0]^)); TRACE(dsc[0].flags); END TestAlloc; BEGIN Modules.InstallTermHandler(Cleanup); END RTL8136. (* MAC address 00-30-4F-25-BB-DB MAC address 00-08-A1-3C-06-CB local IP 129.132.134.209 SystemTools.Free RTL8136 ~ RTL8136.Install ~ WMPerfMon.Open ~ RTL8136.DebugStati ~ IP.IPConfig ~ RTL8136.TestDevices~ OFSTools.Mount RAM RamFS 300000 4096 ~ TestNet.SetDevice "RTL8105E#0" ~ TestNet.ShowDevices ~ TestNet.SendBroadcast ~ TestNet.SendBroadcastVar 1499 ~ TestNet.SendTest ^ 1 10 100 1000 ~ *)