18743ddd8SMarcel Moolenaar#!/usr/bin/env python 28743ddd8SMarcel Moolenaar# 38743ddd8SMarcel Moolenaar# Copyright (c) 2014 Marcel Moolenaar 48743ddd8SMarcel Moolenaar# All rights reserved. 58743ddd8SMarcel Moolenaar# 68743ddd8SMarcel Moolenaar# Redistribution and use in source and binary forms, with or without 78743ddd8SMarcel Moolenaar# modification, are permitted provided that the following conditions 88743ddd8SMarcel Moolenaar# are met: 98743ddd8SMarcel Moolenaar# 108743ddd8SMarcel Moolenaar# 1. Redistributions of source code must retain the above copyright 118743ddd8SMarcel Moolenaar# notice, this list of conditions and the following disclaimer. 128743ddd8SMarcel Moolenaar# 2. Redistributions in binary form must reproduce the above copyright 138743ddd8SMarcel Moolenaar# notice, this list of conditions and the following disclaimer in the 148743ddd8SMarcel Moolenaar# documentation and/or other materials provided with the distribution. 158743ddd8SMarcel Moolenaar# 168743ddd8SMarcel Moolenaar# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 178743ddd8SMarcel Moolenaar# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 188743ddd8SMarcel Moolenaar# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 198743ddd8SMarcel Moolenaar# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 208743ddd8SMarcel Moolenaar# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 218743ddd8SMarcel Moolenaar# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 228743ddd8SMarcel Moolenaar# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 238743ddd8SMarcel Moolenaar# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 248743ddd8SMarcel Moolenaar# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 258743ddd8SMarcel Moolenaar# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 268743ddd8SMarcel Moolenaar# 278743ddd8SMarcel Moolenaar# 288743ddd8SMarcel Moolenaar 298743ddd8SMarcel Moolenaar''' 308743ddd8SMarcel MoolenaarSimple diagnostics program fo the AMD Am89c900 series ILACC. 318743ddd8SMarcel MoolenaarThis ethernet controller is emulated by VMware Fusion among 328743ddd8SMarcel Moolenaarpossibly other virtualization platforms. 338743ddd8SMarcel Moolenaar 348743ddd8SMarcel MoolenaarThe datasheet can be found here: 358743ddd8SMarcel Moolenaar http://support.amd.com/TechDocs/18219.pdf 368743ddd8SMarcel Moolenaar 378743ddd8SMarcel MoolenaarThis example program sends a single DHCP discovery packet, 388743ddd8SMarcel Moolenaarwaits 2 seconds and then iterates over the receive ring for 398743ddd8SMarcel Moolenaara targeted packet. 408743ddd8SMarcel Moolenaar 418743ddd8SMarcel MoolenaarFor this program to function, connect the network interface 428743ddd8SMarcel Moolenaarto a network with a DHCP server. In VMware Fusion this can 438743ddd8SMarcel Moolenaarbest be done by configuring the interface as a NAT interface 448743ddd8SMarcel Moolenaarusing the "Share with my Mac" setting. 458743ddd8SMarcel Moolenaar''' 468743ddd8SMarcel Moolenaar 478743ddd8SMarcel Moolenaarimport ctypes 488743ddd8SMarcel Moolenaarimport logging 498743ddd8SMarcel Moolenaarimport os 508743ddd8SMarcel Moolenaarimport sys 518743ddd8SMarcel Moolenaarimport time 528743ddd8SMarcel Moolenaar 538743ddd8SMarcel Moolenaarsys.path.append('/usr/lib') 548743ddd8SMarcel Moolenaar 558743ddd8SMarcel Moolenaarimport bus 56*da4f5bdaSMarcel Moolenaarfrom bus import dma as busdma 578743ddd8SMarcel Moolenaar 588743ddd8SMarcel Moolenaar 598743ddd8SMarcel Moolenaar# ILACC initialization block definition 608743ddd8SMarcel Moolenaarclass initblock(ctypes.LittleEndianStructure): 618743ddd8SMarcel Moolenaar _fields_ = [('mode', ctypes.c_uint32), 628743ddd8SMarcel Moolenaar ('hwaddr', ctypes.c_uint8 * 6), 638743ddd8SMarcel Moolenaar ('_pad1_', ctypes.c_uint16), 648743ddd8SMarcel Moolenaar ('filter', ctypes.c_uint16 * 4), 658743ddd8SMarcel Moolenaar ('rxdesc', ctypes.c_uint32), 668743ddd8SMarcel Moolenaar ('txdesc', ctypes.c_uint32), 678743ddd8SMarcel Moolenaar ('_pad2_', ctypes.c_uint32)] 688743ddd8SMarcel Moolenaar 698743ddd8SMarcel Moolenaar 708743ddd8SMarcel Moolenaar# ILACC ring buffer descriptor 718743ddd8SMarcel Moolenaarclass bufdesc(ctypes.LittleEndianStructure): 728743ddd8SMarcel Moolenaar _fields_ = [('buffer', ctypes.c_uint32), 738743ddd8SMarcel Moolenaar ('flags', ctypes.c_uint32), 748743ddd8SMarcel Moolenaar ('length', ctypes.c_uint32), 758743ddd8SMarcel Moolenaar ('_pad_', ctypes.c_uint32)] 768743ddd8SMarcel Moolenaar 778743ddd8SMarcel Moolenaar 788743ddd8SMarcel Moolenaar# The DHCP packet definition (incl. all headers) 798743ddd8SMarcel Moolenaarclass packet(ctypes.BigEndianStructure): 808743ddd8SMarcel Moolenaar _pack_ = 1 818743ddd8SMarcel Moolenaar _fields_ = [('eth_dest', ctypes.c_uint8 * 6), 828743ddd8SMarcel Moolenaar ('eth_src', ctypes.c_uint8 * 6), 838743ddd8SMarcel Moolenaar ('eth_type', ctypes.c_uint16), 848743ddd8SMarcel Moolenaar ('ip_vl', ctypes.c_uint8), 858743ddd8SMarcel Moolenaar ('ip_de', ctypes.c_uint8), 868743ddd8SMarcel Moolenaar ('ip_len', ctypes.c_uint16), 878743ddd8SMarcel Moolenaar ('ip_id', ctypes.c_uint16), 888743ddd8SMarcel Moolenaar ('ip_ff', ctypes.c_uint16), 898743ddd8SMarcel Moolenaar ('ip_ttl', ctypes.c_uint8), 908743ddd8SMarcel Moolenaar ('ip_proto', ctypes.c_uint8), 918743ddd8SMarcel Moolenaar ('ip_cksum', ctypes.c_uint16), 928743ddd8SMarcel Moolenaar ('ip_src', ctypes.c_uint32), 938743ddd8SMarcel Moolenaar ('ip_dest', ctypes.c_uint32), 948743ddd8SMarcel Moolenaar ('udp_src', ctypes.c_uint16), 958743ddd8SMarcel Moolenaar ('udp_dest', ctypes.c_uint16), 968743ddd8SMarcel Moolenaar ('udp_len', ctypes.c_uint16), 978743ddd8SMarcel Moolenaar ('udp_cksum', ctypes.c_uint16), 988743ddd8SMarcel Moolenaar ('bootp_op', ctypes.c_uint8), 998743ddd8SMarcel Moolenaar ('bootp_htype', ctypes.c_uint8), 1008743ddd8SMarcel Moolenaar ('bootp_hlen', ctypes.c_uint8), 1018743ddd8SMarcel Moolenaar ('bootp_hops', ctypes.c_uint8), 1028743ddd8SMarcel Moolenaar ('bootp_xid', ctypes.c_uint32), 1038743ddd8SMarcel Moolenaar ('bootp_secs', ctypes.c_uint16), 1048743ddd8SMarcel Moolenaar ('bootp_flags', ctypes.c_uint16), 1058743ddd8SMarcel Moolenaar ('bootp_ciaddr', ctypes.c_uint32), 1068743ddd8SMarcel Moolenaar ('bootp_yiaddr', ctypes.c_uint32), 1078743ddd8SMarcel Moolenaar ('bootp_siaddr', ctypes.c_uint32), 1088743ddd8SMarcel Moolenaar ('bootp_giaddr', ctypes.c_uint32), 1098743ddd8SMarcel Moolenaar ('bootp_chaddr', ctypes.c_uint8 * 16), 1108743ddd8SMarcel Moolenaar ('bootp_sname', ctypes.c_uint8 * 64), 1118743ddd8SMarcel Moolenaar ('bootp_file', ctypes.c_uint8 * 128), 1128743ddd8SMarcel Moolenaar ('dhcp_magic', ctypes.c_uint32), 1138743ddd8SMarcel Moolenaar ('dhcp_options', ctypes.c_uint8 * 60)] 1148743ddd8SMarcel Moolenaar 1158743ddd8SMarcel MoolenaarMACFMT = '%02x:%02x:%02x:%02x:%02x:%02x' 1168743ddd8SMarcel Moolenaar 1178743ddd8SMarcel Moolenaardev = 'pci0:2:1:0' 1188743ddd8SMarcel Moolenaar 1198743ddd8SMarcel Moolenaarlogging.basicConfig(level=logging.DEBUG) 1208743ddd8SMarcel Moolenaar 1218743ddd8SMarcel Moolenaarpcicfg = bus.map(dev, 'pcicfg') 1228743ddd8SMarcel Moolenaarlogging.debug('pcicfg=%s (%s)' % (pcicfg, dev)) 1238743ddd8SMarcel Moolenaar 1248743ddd8SMarcel Moolenaarvendor = bus.read_2(pcicfg, 0) 1258743ddd8SMarcel Moolenaardevice = bus.read_2(pcicfg, 2) 1268743ddd8SMarcel Moolenaarif vendor != 0x1022 or device != 0x2000: 1278743ddd8SMarcel Moolenaar logging.error('Not an AMD PCnet-PCI (vendor=%x, device=%x)' % 1288743ddd8SMarcel Moolenaar (vendor, device)) 1298743ddd8SMarcel Moolenaar sys.exit(1) 1308743ddd8SMarcel Moolenaar 1318743ddd8SMarcel Moolenaarcommand = bus.read_2(pcicfg, 4) 1328743ddd8SMarcel Moolenaarif not (command & 1): 1338743ddd8SMarcel Moolenaar logging.info('enabling I/O port decoding') 1348743ddd8SMarcel Moolenaar command |= 1 1358743ddd8SMarcel Moolenaar bus.write_2(pcicfg, 4, command) 1368743ddd8SMarcel Moolenaar 1378743ddd8SMarcel Moolenaarif not (command & 4): 1388743ddd8SMarcel Moolenaar logging.info('enabling bus mastering') 1398743ddd8SMarcel Moolenaar command |= 4 1408743ddd8SMarcel Moolenaar bus.write_2(pcicfg, 4, command) 1418743ddd8SMarcel Moolenaar 1428743ddd8SMarcel Moolenaarbus.unmap(pcicfg) 1438743ddd8SMarcel Moolenaar 1448743ddd8SMarcel Moolenaario = bus.map(dev, '10.io') 1458743ddd8SMarcel Moolenaarlogging.debug('io=%s (%s)' % (io, dev)) 1468743ddd8SMarcel Moolenaar 1478743ddd8SMarcel Moolenaar 1488743ddd8SMarcel Moolenaardef delay(msec): 1498743ddd8SMarcel Moolenaar time.sleep(msec / 1000.0) 1508743ddd8SMarcel Moolenaar 1518743ddd8SMarcel Moolenaar 1528743ddd8SMarcel Moolenaardef ffs(x): 1538743ddd8SMarcel Moolenaar y = (1 + (x ^ (x-1))) >> 1 1548743ddd8SMarcel Moolenaar return y.bit_length() 1558743ddd8SMarcel Moolenaar 1568743ddd8SMarcel Moolenaar 1578743ddd8SMarcel Moolenaardef ip_str(a): 1588743ddd8SMarcel Moolenaar return '%d.%d.%d.%d' % ((a >> 24) & 255, (a >> 16) & 255, (a >> 8) & 255, 1598743ddd8SMarcel Moolenaar a & 255) 1608743ddd8SMarcel Moolenaar 1618743ddd8SMarcel Moolenaar 1628743ddd8SMarcel Moolenaardef mac_is(l, r): 163*da4f5bdaSMarcel Moolenaar for i in range(6): 1648743ddd8SMarcel Moolenaar if l[i] != r[i]: 1658743ddd8SMarcel Moolenaar return False 1668743ddd8SMarcel Moolenaar return True 1678743ddd8SMarcel Moolenaar 1688743ddd8SMarcel Moolenaar 1698743ddd8SMarcel Moolenaardef mac_str(m): 1708743ddd8SMarcel Moolenaar return MACFMT % (m[0], m[1], m[2], m[3], m[4], m[5]) 1718743ddd8SMarcel Moolenaar 1728743ddd8SMarcel Moolenaar 1738743ddd8SMarcel Moolenaardef rdbcr(reg): 1748743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1758743ddd8SMarcel Moolenaar return bus.read_2(io, 0x16) 1768743ddd8SMarcel Moolenaar 1778743ddd8SMarcel Moolenaar 1788743ddd8SMarcel Moolenaardef wrbcr(reg, val): 1798743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1808743ddd8SMarcel Moolenaar bus.write_2(io, 0x16, val & 0xffff) 1818743ddd8SMarcel Moolenaar 1828743ddd8SMarcel Moolenaar 1838743ddd8SMarcel Moolenaardef rdcsr(reg): 1848743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1858743ddd8SMarcel Moolenaar return bus.read_2(io, 0x10) 1868743ddd8SMarcel Moolenaar 1878743ddd8SMarcel Moolenaar 1888743ddd8SMarcel Moolenaardef wrcsr(reg, val): 1898743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1908743ddd8SMarcel Moolenaar bus.write_2(io, 0x10, val & 0xffff) 1918743ddd8SMarcel Moolenaar 1928743ddd8SMarcel Moolenaar 1938743ddd8SMarcel Moolenaardef start(): 1948743ddd8SMarcel Moolenaar wrcsr(0, 0x42) 1958743ddd8SMarcel Moolenaar delay(100) 1968743ddd8SMarcel Moolenaar 1978743ddd8SMarcel Moolenaar 1988743ddd8SMarcel Moolenaardef stop(): 1998743ddd8SMarcel Moolenaar wrcsr(0, 4) 2008743ddd8SMarcel Moolenaar delay(100) 2018743ddd8SMarcel Moolenaar 2028743ddd8SMarcel Moolenaar 2038743ddd8SMarcel Moolenaarmac = () 2048743ddd8SMarcel Moolenaarbcast = () 205*da4f5bdaSMarcel Moolenaarfor o in range(6): 2068743ddd8SMarcel Moolenaar mac += (bus.read_1(io, o),) 2078743ddd8SMarcel Moolenaar bcast += (0xff,) 2088743ddd8SMarcel Moolenaarlogging.info('ethernet address = ' + MACFMT % mac) 2098743ddd8SMarcel Moolenaar 2108743ddd8SMarcel Moolenaarstop() 2118743ddd8SMarcel Moolenaarwrbcr(20, 2) # reset 2128743ddd8SMarcel Moolenaarwrcsr(3, 0) # byte swapping mode 2138743ddd8SMarcel Moolenaarwrbcr(2, rdbcr(2) | 2) # Autoneg 2148743ddd8SMarcel Moolenaar 2158743ddd8SMarcel Moolenaarmemsize = 32*1024 2168743ddd8SMarcel Moolenaarbufsize = 1536 2178743ddd8SMarcel Moolenaarnrxbufs = 16 2188743ddd8SMarcel Moolenaarntxbufs = 4 2198743ddd8SMarcel Moolenaarlogging.debug("DMA memory: size = %#x (TX buffers: %u, RX buffers: %u)" % 2208743ddd8SMarcel Moolenaar (memsize, ntxbufs, nrxbufs)) 2218743ddd8SMarcel Moolenaar 2228743ddd8SMarcel Moolenaarmem_tag = busdma.tag_create(dev, 16, 0, 0xffffffff, memsize, 1, memsize, 0, 0) 2238743ddd8SMarcel Moolenaardmamem = busdma.mem_alloc(mem_tag, 0) 2248743ddd8SMarcel Moolenaarbusseg = busdma.md_first_seg(dmamem, busdma.MD_BUS_SPACE) 2258743ddd8SMarcel Moolenaarcpuseg = busdma.md_first_seg(dmamem, busdma.MD_VIRT_SPACE) 2268743ddd8SMarcel Moolenaarbusaddr = busdma.seg_get_addr(busseg) 2278743ddd8SMarcel Moolenaarcpuaddr = busdma.seg_get_addr(cpuseg) 2288743ddd8SMarcel Moolenaarlogging.debug("DMA memory: CPU address: %#x, device address: %#x" % 2298743ddd8SMarcel Moolenaar (cpuaddr, busaddr)) 2308743ddd8SMarcel Moolenaar 2318743ddd8SMarcel Moolenaaraddr_initblock = cpuaddr 2328743ddd8SMarcel Moolenaaraddr_rxdesc = addr_initblock + ctypes.sizeof(initblock) 2338743ddd8SMarcel Moolenaaraddr_txdesc = addr_rxdesc + ctypes.sizeof(bufdesc) * nrxbufs 2348743ddd8SMarcel Moolenaaraddr_rxbufs = addr_txdesc + ctypes.sizeof(bufdesc) * ntxbufs 2358743ddd8SMarcel Moolenaaraddr_txbufs = addr_rxbufs + bufsize * nrxbufs 2368743ddd8SMarcel Moolenaar 2378743ddd8SMarcel Moolenaarib = initblock.from_address(addr_initblock) 2388743ddd8SMarcel Moolenaarib.mode = ((ffs(ntxbufs) - 1) << 28) | ((ffs(nrxbufs) - 1) << 20) 239*da4f5bdaSMarcel Moolenaarfor i in range(len(mac)): 2408743ddd8SMarcel Moolenaar ib.hwaddr[i] = mac[i] 241*da4f5bdaSMarcel Moolenaarfor i in range(4): 2428743ddd8SMarcel Moolenaar ib.filter[i] = 0xffff 2438743ddd8SMarcel Moolenaarib.rxdesc = busaddr + (addr_rxdesc - cpuaddr) 2448743ddd8SMarcel Moolenaarib.txdesc = busaddr + (addr_txdesc - cpuaddr) 2458743ddd8SMarcel Moolenaarib._pad1_ = 0 2468743ddd8SMarcel Moolenaarib._pad2_ = 0 2478743ddd8SMarcel Moolenaar 248*da4f5bdaSMarcel Moolenaarfor i in range(nrxbufs): 2498743ddd8SMarcel Moolenaar bd = bufdesc.from_address(addr_rxdesc + ctypes.sizeof(bufdesc) * i) 2508743ddd8SMarcel Moolenaar bd.buffer = busaddr + (addr_rxbufs - cpuaddr) + bufsize * i 2518743ddd8SMarcel Moolenaar bd.flags = (1 << 31) | (15 << 12) | (-bufsize & 0xfff) 2528743ddd8SMarcel Moolenaar bd.length = 0 2538743ddd8SMarcel Moolenaar bd._pad_ = 0 2548743ddd8SMarcel Moolenaar 255*da4f5bdaSMarcel Moolenaarfor i in range(ntxbufs): 2568743ddd8SMarcel Moolenaar bd = bufdesc.from_address(addr_txdesc + ctypes.sizeof(bufdesc) * i) 2578743ddd8SMarcel Moolenaar bd.buffer = busaddr + (addr_txbufs - cpuaddr) + bufsize * i 2588743ddd8SMarcel Moolenaar bd.flags = (15 << 12) 2598743ddd8SMarcel Moolenaar bd.length = 0 2608743ddd8SMarcel Moolenaar bd._pad_ = 0 2618743ddd8SMarcel Moolenaar 2628743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, 0, addr_rxbufs - cpuaddr) 2638743ddd8SMarcel Moolenaar 2648743ddd8SMarcel Moolenaar# Program address of DMA memory 2658743ddd8SMarcel Moolenaarwrcsr(1, busaddr) 2668743ddd8SMarcel Moolenaarwrcsr(2, busaddr >> 16) 2678743ddd8SMarcel Moolenaardelay(100) 2688743ddd8SMarcel Moolenaar 2698743ddd8SMarcel Moolenaar# Initialize hardware 2708743ddd8SMarcel Moolenaarwrcsr(0, 1) 2718743ddd8SMarcel Moolenaarlogging.debug('Waiting for initialization to complete') 2728743ddd8SMarcel Moolenaarcsr = rdcsr(0) 2738743ddd8SMarcel Moolenaarwhile (csr & 0x100) == 0: 2748743ddd8SMarcel Moolenaar logging.debug('CSR=%#x' % (csr)) 2758743ddd8SMarcel Moolenaar csr = rdcsr(0) 2768743ddd8SMarcel Moolenaar 2778743ddd8SMarcel Moolenaarstart() 2788743ddd8SMarcel Moolenaar 2798743ddd8SMarcel Moolenaarpkt = packet.from_address(addr_txbufs) 2808743ddd8SMarcel Moolenaarctypes.memset(addr_txbufs, 0, ctypes.sizeof(pkt)) 2818743ddd8SMarcel Moolenaaroptions = [53, 1, 1] 282*da4f5bdaSMarcel Moolenaarfor i in range(len(options)): 2838743ddd8SMarcel Moolenaar pkt.dhcp_options[i] = options[i] 2848743ddd8SMarcel Moolenaarpkt.dhcp_magic = 0x63825363 285*da4f5bdaSMarcel Moolenaarfor i in range(6): 2868743ddd8SMarcel Moolenaar pkt.bootp_chaddr[i] = mac[i] 2878743ddd8SMarcel Moolenaarpkt.bootp_hlen = 6 2888743ddd8SMarcel Moolenaarpkt.bootp_htype = 1 2898743ddd8SMarcel Moolenaarpkt.bootp_op = 1 2908743ddd8SMarcel Moolenaarpkt.udp_len = ctypes.sizeof(pkt) - 34 2918743ddd8SMarcel Moolenaarpkt.udp_dest = 67 2928743ddd8SMarcel Moolenaarpkt.udp_src = 68 2938743ddd8SMarcel Moolenaarpkt.ip_dest = 0xffffffff 2948743ddd8SMarcel Moolenaarpkt.ip_cksum = 0x79a6 2958743ddd8SMarcel Moolenaarpkt.ip_proto = 17 2968743ddd8SMarcel Moolenaarpkt.ip_ttl = 64 2978743ddd8SMarcel Moolenaarpkt.ip_len = ctypes.sizeof(pkt) - 14 2988743ddd8SMarcel Moolenaarpkt.ip_vl = 0x45 2998743ddd8SMarcel Moolenaarpkt.eth_type = 0x0800 300*da4f5bdaSMarcel Moolenaarfor i in range(6): 3018743ddd8SMarcel Moolenaar pkt.eth_src[i] = mac[i] 3028743ddd8SMarcel Moolenaar pkt.eth_dest[i] = bcast[i] 3038743ddd8SMarcel Moolenaarpktlen = ctypes.sizeof(pkt) 3048743ddd8SMarcel Moolenaar 3058743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_txbufs - cpuaddr, bufsize) 3068743ddd8SMarcel Moolenaar 3078743ddd8SMarcel Moolenaarbd = bufdesc.from_address(addr_txdesc) 3088743ddd8SMarcel Moolenaarbd.length = 0 3098743ddd8SMarcel Moolenaarbd.flags = (1 << 31) | (1 << 25) | (1 << 24) | (0xf << 12) | (-pktlen & 0xfff) 3108743ddd8SMarcel Moolenaar 3118743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_txdesc - cpuaddr, 3128743ddd8SMarcel Moolenaar ctypes.sizeof(bufdesc)) 3138743ddd8SMarcel Moolenaar 3148743ddd8SMarcel Moolenaarwrcsr(0, 0x48) 3158743ddd8SMarcel Moolenaar 3168743ddd8SMarcel Moolenaarlogging.info('DHCP discovery packet sent') 3178743ddd8SMarcel Moolenaar 3188743ddd8SMarcel Moolenaar# Now wait 2 seconds for a DHCP offer to be received. 3198743ddd8SMarcel Moolenaarlogging.debug('Waiting 2 seconds for an offer to be received') 3208743ddd8SMarcel Moolenaartime.sleep(2) 3218743ddd8SMarcel Moolenaar 3228743ddd8SMarcel Moolenaarstop() 3238743ddd8SMarcel Moolenaar 3248743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_rxdesc - cpuaddr, 3258743ddd8SMarcel Moolenaar ctypes.sizeof(bufdesc) * nrxbufs) 3268743ddd8SMarcel Moolenaar 327*da4f5bdaSMarcel Moolenaarfor i in range(nrxbufs): 3288743ddd8SMarcel Moolenaar bd = bufdesc.from_address(addr_rxdesc + ctypes.sizeof(bufdesc) * i) 3298743ddd8SMarcel Moolenaar if (bd.flags & 0x80000000): 3308743ddd8SMarcel Moolenaar continue 3318743ddd8SMarcel Moolenaar pkt = packet.from_address(addr_rxbufs + i * bufsize) 3328743ddd8SMarcel Moolenaar if mac_is(pkt.eth_dest, bcast): 3338743ddd8SMarcel Moolenaar logging.debug('RX #%d: broadcast packet: length %u' % (i, bd.length)) 3348743ddd8SMarcel Moolenaar continue 3358743ddd8SMarcel Moolenaar if not mac_is(pkt.eth_dest, mac): 3368743ddd8SMarcel Moolenaar logging.debug('RX #%d: packet for %s?' % (i, mac_str(pkt.eth_dest))) 3378743ddd8SMarcel Moolenaar continue 3388743ddd8SMarcel Moolenaar logging.debug('RX %d: packet from %s!' % (i, mac_str(pkt.eth_src))) 3398743ddd8SMarcel Moolenaar logging.info('Our IP address = %s' % (ip_str(pkt.ip_dest))) 3408743ddd8SMarcel Moolenaar 3418743ddd8SMarcel Moolenaarbusdma.mem_free(dmamem) 3428743ddd8SMarcel Moolenaarbusdma.tag_destroy(mem_tag) 3438743ddd8SMarcel Moolenaarbus.unmap(io) 344