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# $FreeBSD$ 288743ddd8SMarcel Moolenaar# 298743ddd8SMarcel Moolenaar 308743ddd8SMarcel Moolenaar''' 318743ddd8SMarcel MoolenaarSimple diagnostics program fo the AMD Am89c900 series ILACC. 328743ddd8SMarcel MoolenaarThis ethernet controller is emulated by VMware Fusion among 338743ddd8SMarcel Moolenaarpossibly other virtualization platforms. 348743ddd8SMarcel Moolenaar 358743ddd8SMarcel MoolenaarThe datasheet can be found here: 368743ddd8SMarcel Moolenaar http://support.amd.com/TechDocs/18219.pdf 378743ddd8SMarcel Moolenaar 388743ddd8SMarcel MoolenaarThis example program sends a single DHCP discovery packet, 398743ddd8SMarcel Moolenaarwaits 2 seconds and then iterates over the receive ring for 408743ddd8SMarcel Moolenaara targeted packet. 418743ddd8SMarcel Moolenaar 428743ddd8SMarcel MoolenaarFor this program to function, connect the network interface 438743ddd8SMarcel Moolenaarto a network with a DHCP server. In VMware Fusion this can 448743ddd8SMarcel Moolenaarbest be done by configuring the interface as a NAT interface 458743ddd8SMarcel Moolenaarusing the "Share with my Mac" setting. 468743ddd8SMarcel Moolenaar''' 478743ddd8SMarcel Moolenaar 488743ddd8SMarcel Moolenaarimport ctypes 498743ddd8SMarcel Moolenaarimport logging 508743ddd8SMarcel Moolenaarimport os 518743ddd8SMarcel Moolenaarimport sys 528743ddd8SMarcel Moolenaarimport time 538743ddd8SMarcel Moolenaar 548743ddd8SMarcel Moolenaarsys.path.append('/usr/lib') 558743ddd8SMarcel Moolenaar 568743ddd8SMarcel Moolenaarimport bus 57*da4f5bdaSMarcel Moolenaarfrom bus import dma as busdma 588743ddd8SMarcel Moolenaar 598743ddd8SMarcel Moolenaar 608743ddd8SMarcel Moolenaar# ILACC initialization block definition 618743ddd8SMarcel Moolenaarclass initblock(ctypes.LittleEndianStructure): 628743ddd8SMarcel Moolenaar _fields_ = [('mode', ctypes.c_uint32), 638743ddd8SMarcel Moolenaar ('hwaddr', ctypes.c_uint8 * 6), 648743ddd8SMarcel Moolenaar ('_pad1_', ctypes.c_uint16), 658743ddd8SMarcel Moolenaar ('filter', ctypes.c_uint16 * 4), 668743ddd8SMarcel Moolenaar ('rxdesc', ctypes.c_uint32), 678743ddd8SMarcel Moolenaar ('txdesc', ctypes.c_uint32), 688743ddd8SMarcel Moolenaar ('_pad2_', ctypes.c_uint32)] 698743ddd8SMarcel Moolenaar 708743ddd8SMarcel Moolenaar 718743ddd8SMarcel Moolenaar# ILACC ring buffer descriptor 728743ddd8SMarcel Moolenaarclass bufdesc(ctypes.LittleEndianStructure): 738743ddd8SMarcel Moolenaar _fields_ = [('buffer', ctypes.c_uint32), 748743ddd8SMarcel Moolenaar ('flags', ctypes.c_uint32), 758743ddd8SMarcel Moolenaar ('length', ctypes.c_uint32), 768743ddd8SMarcel Moolenaar ('_pad_', ctypes.c_uint32)] 778743ddd8SMarcel Moolenaar 788743ddd8SMarcel Moolenaar 798743ddd8SMarcel Moolenaar# The DHCP packet definition (incl. all headers) 808743ddd8SMarcel Moolenaarclass packet(ctypes.BigEndianStructure): 818743ddd8SMarcel Moolenaar _pack_ = 1 828743ddd8SMarcel Moolenaar _fields_ = [('eth_dest', ctypes.c_uint8 * 6), 838743ddd8SMarcel Moolenaar ('eth_src', ctypes.c_uint8 * 6), 848743ddd8SMarcel Moolenaar ('eth_type', ctypes.c_uint16), 858743ddd8SMarcel Moolenaar ('ip_vl', ctypes.c_uint8), 868743ddd8SMarcel Moolenaar ('ip_de', ctypes.c_uint8), 878743ddd8SMarcel Moolenaar ('ip_len', ctypes.c_uint16), 888743ddd8SMarcel Moolenaar ('ip_id', ctypes.c_uint16), 898743ddd8SMarcel Moolenaar ('ip_ff', ctypes.c_uint16), 908743ddd8SMarcel Moolenaar ('ip_ttl', ctypes.c_uint8), 918743ddd8SMarcel Moolenaar ('ip_proto', ctypes.c_uint8), 928743ddd8SMarcel Moolenaar ('ip_cksum', ctypes.c_uint16), 938743ddd8SMarcel Moolenaar ('ip_src', ctypes.c_uint32), 948743ddd8SMarcel Moolenaar ('ip_dest', ctypes.c_uint32), 958743ddd8SMarcel Moolenaar ('udp_src', ctypes.c_uint16), 968743ddd8SMarcel Moolenaar ('udp_dest', ctypes.c_uint16), 978743ddd8SMarcel Moolenaar ('udp_len', ctypes.c_uint16), 988743ddd8SMarcel Moolenaar ('udp_cksum', ctypes.c_uint16), 998743ddd8SMarcel Moolenaar ('bootp_op', ctypes.c_uint8), 1008743ddd8SMarcel Moolenaar ('bootp_htype', ctypes.c_uint8), 1018743ddd8SMarcel Moolenaar ('bootp_hlen', ctypes.c_uint8), 1028743ddd8SMarcel Moolenaar ('bootp_hops', ctypes.c_uint8), 1038743ddd8SMarcel Moolenaar ('bootp_xid', ctypes.c_uint32), 1048743ddd8SMarcel Moolenaar ('bootp_secs', ctypes.c_uint16), 1058743ddd8SMarcel Moolenaar ('bootp_flags', ctypes.c_uint16), 1068743ddd8SMarcel Moolenaar ('bootp_ciaddr', ctypes.c_uint32), 1078743ddd8SMarcel Moolenaar ('bootp_yiaddr', ctypes.c_uint32), 1088743ddd8SMarcel Moolenaar ('bootp_siaddr', ctypes.c_uint32), 1098743ddd8SMarcel Moolenaar ('bootp_giaddr', ctypes.c_uint32), 1108743ddd8SMarcel Moolenaar ('bootp_chaddr', ctypes.c_uint8 * 16), 1118743ddd8SMarcel Moolenaar ('bootp_sname', ctypes.c_uint8 * 64), 1128743ddd8SMarcel Moolenaar ('bootp_file', ctypes.c_uint8 * 128), 1138743ddd8SMarcel Moolenaar ('dhcp_magic', ctypes.c_uint32), 1148743ddd8SMarcel Moolenaar ('dhcp_options', ctypes.c_uint8 * 60)] 1158743ddd8SMarcel Moolenaar 1168743ddd8SMarcel MoolenaarMACFMT = '%02x:%02x:%02x:%02x:%02x:%02x' 1178743ddd8SMarcel Moolenaar 1188743ddd8SMarcel Moolenaardev = 'pci0:2:1:0' 1198743ddd8SMarcel Moolenaar 1208743ddd8SMarcel Moolenaarlogging.basicConfig(level=logging.DEBUG) 1218743ddd8SMarcel Moolenaar 1228743ddd8SMarcel Moolenaarpcicfg = bus.map(dev, 'pcicfg') 1238743ddd8SMarcel Moolenaarlogging.debug('pcicfg=%s (%s)' % (pcicfg, dev)) 1248743ddd8SMarcel Moolenaar 1258743ddd8SMarcel Moolenaarvendor = bus.read_2(pcicfg, 0) 1268743ddd8SMarcel Moolenaardevice = bus.read_2(pcicfg, 2) 1278743ddd8SMarcel Moolenaarif vendor != 0x1022 or device != 0x2000: 1288743ddd8SMarcel Moolenaar logging.error('Not an AMD PCnet-PCI (vendor=%x, device=%x)' % 1298743ddd8SMarcel Moolenaar (vendor, device)) 1308743ddd8SMarcel Moolenaar sys.exit(1) 1318743ddd8SMarcel Moolenaar 1328743ddd8SMarcel Moolenaarcommand = bus.read_2(pcicfg, 4) 1338743ddd8SMarcel Moolenaarif not (command & 1): 1348743ddd8SMarcel Moolenaar logging.info('enabling I/O port decoding') 1358743ddd8SMarcel Moolenaar command |= 1 1368743ddd8SMarcel Moolenaar bus.write_2(pcicfg, 4, command) 1378743ddd8SMarcel Moolenaar 1388743ddd8SMarcel Moolenaarif not (command & 4): 1398743ddd8SMarcel Moolenaar logging.info('enabling bus mastering') 1408743ddd8SMarcel Moolenaar command |= 4 1418743ddd8SMarcel Moolenaar bus.write_2(pcicfg, 4, command) 1428743ddd8SMarcel Moolenaar 1438743ddd8SMarcel Moolenaarbus.unmap(pcicfg) 1448743ddd8SMarcel Moolenaar 1458743ddd8SMarcel Moolenaario = bus.map(dev, '10.io') 1468743ddd8SMarcel Moolenaarlogging.debug('io=%s (%s)' % (io, dev)) 1478743ddd8SMarcel Moolenaar 1488743ddd8SMarcel Moolenaar 1498743ddd8SMarcel Moolenaardef delay(msec): 1508743ddd8SMarcel Moolenaar time.sleep(msec / 1000.0) 1518743ddd8SMarcel Moolenaar 1528743ddd8SMarcel Moolenaar 1538743ddd8SMarcel Moolenaardef ffs(x): 1548743ddd8SMarcel Moolenaar y = (1 + (x ^ (x-1))) >> 1 1558743ddd8SMarcel Moolenaar return y.bit_length() 1568743ddd8SMarcel Moolenaar 1578743ddd8SMarcel Moolenaar 1588743ddd8SMarcel Moolenaardef ip_str(a): 1598743ddd8SMarcel Moolenaar return '%d.%d.%d.%d' % ((a >> 24) & 255, (a >> 16) & 255, (a >> 8) & 255, 1608743ddd8SMarcel Moolenaar a & 255) 1618743ddd8SMarcel Moolenaar 1628743ddd8SMarcel Moolenaar 1638743ddd8SMarcel Moolenaardef mac_is(l, r): 164*da4f5bdaSMarcel Moolenaar for i in range(6): 1658743ddd8SMarcel Moolenaar if l[i] != r[i]: 1668743ddd8SMarcel Moolenaar return False 1678743ddd8SMarcel Moolenaar return True 1688743ddd8SMarcel Moolenaar 1698743ddd8SMarcel Moolenaar 1708743ddd8SMarcel Moolenaardef mac_str(m): 1718743ddd8SMarcel Moolenaar return MACFMT % (m[0], m[1], m[2], m[3], m[4], m[5]) 1728743ddd8SMarcel Moolenaar 1738743ddd8SMarcel Moolenaar 1748743ddd8SMarcel Moolenaardef rdbcr(reg): 1758743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1768743ddd8SMarcel Moolenaar return bus.read_2(io, 0x16) 1778743ddd8SMarcel Moolenaar 1788743ddd8SMarcel Moolenaar 1798743ddd8SMarcel Moolenaardef wrbcr(reg, val): 1808743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1818743ddd8SMarcel Moolenaar bus.write_2(io, 0x16, val & 0xffff) 1828743ddd8SMarcel Moolenaar 1838743ddd8SMarcel Moolenaar 1848743ddd8SMarcel Moolenaardef rdcsr(reg): 1858743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1868743ddd8SMarcel Moolenaar return bus.read_2(io, 0x10) 1878743ddd8SMarcel Moolenaar 1888743ddd8SMarcel Moolenaar 1898743ddd8SMarcel Moolenaardef wrcsr(reg, val): 1908743ddd8SMarcel Moolenaar bus.write_2(io, 0x12, reg & 0xffff) 1918743ddd8SMarcel Moolenaar bus.write_2(io, 0x10, val & 0xffff) 1928743ddd8SMarcel Moolenaar 1938743ddd8SMarcel Moolenaar 1948743ddd8SMarcel Moolenaardef start(): 1958743ddd8SMarcel Moolenaar wrcsr(0, 0x42) 1968743ddd8SMarcel Moolenaar delay(100) 1978743ddd8SMarcel Moolenaar 1988743ddd8SMarcel Moolenaar 1998743ddd8SMarcel Moolenaardef stop(): 2008743ddd8SMarcel Moolenaar wrcsr(0, 4) 2018743ddd8SMarcel Moolenaar delay(100) 2028743ddd8SMarcel Moolenaar 2038743ddd8SMarcel Moolenaar 2048743ddd8SMarcel Moolenaarmac = () 2058743ddd8SMarcel Moolenaarbcast = () 206*da4f5bdaSMarcel Moolenaarfor o in range(6): 2078743ddd8SMarcel Moolenaar mac += (bus.read_1(io, o),) 2088743ddd8SMarcel Moolenaar bcast += (0xff,) 2098743ddd8SMarcel Moolenaarlogging.info('ethernet address = ' + MACFMT % mac) 2108743ddd8SMarcel Moolenaar 2118743ddd8SMarcel Moolenaarstop() 2128743ddd8SMarcel Moolenaarwrbcr(20, 2) # reset 2138743ddd8SMarcel Moolenaarwrcsr(3, 0) # byte swapping mode 2148743ddd8SMarcel Moolenaarwrbcr(2, rdbcr(2) | 2) # Autoneg 2158743ddd8SMarcel Moolenaar 2168743ddd8SMarcel Moolenaarmemsize = 32*1024 2178743ddd8SMarcel Moolenaarbufsize = 1536 2188743ddd8SMarcel Moolenaarnrxbufs = 16 2198743ddd8SMarcel Moolenaarntxbufs = 4 2208743ddd8SMarcel Moolenaarlogging.debug("DMA memory: size = %#x (TX buffers: %u, RX buffers: %u)" % 2218743ddd8SMarcel Moolenaar (memsize, ntxbufs, nrxbufs)) 2228743ddd8SMarcel Moolenaar 2238743ddd8SMarcel Moolenaarmem_tag = busdma.tag_create(dev, 16, 0, 0xffffffff, memsize, 1, memsize, 0, 0) 2248743ddd8SMarcel Moolenaardmamem = busdma.mem_alloc(mem_tag, 0) 2258743ddd8SMarcel Moolenaarbusseg = busdma.md_first_seg(dmamem, busdma.MD_BUS_SPACE) 2268743ddd8SMarcel Moolenaarcpuseg = busdma.md_first_seg(dmamem, busdma.MD_VIRT_SPACE) 2278743ddd8SMarcel Moolenaarbusaddr = busdma.seg_get_addr(busseg) 2288743ddd8SMarcel Moolenaarcpuaddr = busdma.seg_get_addr(cpuseg) 2298743ddd8SMarcel Moolenaarlogging.debug("DMA memory: CPU address: %#x, device address: %#x" % 2308743ddd8SMarcel Moolenaar (cpuaddr, busaddr)) 2318743ddd8SMarcel Moolenaar 2328743ddd8SMarcel Moolenaaraddr_initblock = cpuaddr 2338743ddd8SMarcel Moolenaaraddr_rxdesc = addr_initblock + ctypes.sizeof(initblock) 2348743ddd8SMarcel Moolenaaraddr_txdesc = addr_rxdesc + ctypes.sizeof(bufdesc) * nrxbufs 2358743ddd8SMarcel Moolenaaraddr_rxbufs = addr_txdesc + ctypes.sizeof(bufdesc) * ntxbufs 2368743ddd8SMarcel Moolenaaraddr_txbufs = addr_rxbufs + bufsize * nrxbufs 2378743ddd8SMarcel Moolenaar 2388743ddd8SMarcel Moolenaarib = initblock.from_address(addr_initblock) 2398743ddd8SMarcel Moolenaarib.mode = ((ffs(ntxbufs) - 1) << 28) | ((ffs(nrxbufs) - 1) << 20) 240*da4f5bdaSMarcel Moolenaarfor i in range(len(mac)): 2418743ddd8SMarcel Moolenaar ib.hwaddr[i] = mac[i] 242*da4f5bdaSMarcel Moolenaarfor i in range(4): 2438743ddd8SMarcel Moolenaar ib.filter[i] = 0xffff 2448743ddd8SMarcel Moolenaarib.rxdesc = busaddr + (addr_rxdesc - cpuaddr) 2458743ddd8SMarcel Moolenaarib.txdesc = busaddr + (addr_txdesc - cpuaddr) 2468743ddd8SMarcel Moolenaarib._pad1_ = 0 2478743ddd8SMarcel Moolenaarib._pad2_ = 0 2488743ddd8SMarcel Moolenaar 249*da4f5bdaSMarcel Moolenaarfor i in range(nrxbufs): 2508743ddd8SMarcel Moolenaar bd = bufdesc.from_address(addr_rxdesc + ctypes.sizeof(bufdesc) * i) 2518743ddd8SMarcel Moolenaar bd.buffer = busaddr + (addr_rxbufs - cpuaddr) + bufsize * i 2528743ddd8SMarcel Moolenaar bd.flags = (1 << 31) | (15 << 12) | (-bufsize & 0xfff) 2538743ddd8SMarcel Moolenaar bd.length = 0 2548743ddd8SMarcel Moolenaar bd._pad_ = 0 2558743ddd8SMarcel Moolenaar 256*da4f5bdaSMarcel Moolenaarfor i in range(ntxbufs): 2578743ddd8SMarcel Moolenaar bd = bufdesc.from_address(addr_txdesc + ctypes.sizeof(bufdesc) * i) 2588743ddd8SMarcel Moolenaar bd.buffer = busaddr + (addr_txbufs - cpuaddr) + bufsize * i 2598743ddd8SMarcel Moolenaar bd.flags = (15 << 12) 2608743ddd8SMarcel Moolenaar bd.length = 0 2618743ddd8SMarcel Moolenaar bd._pad_ = 0 2628743ddd8SMarcel Moolenaar 2638743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, 0, addr_rxbufs - cpuaddr) 2648743ddd8SMarcel Moolenaar 2658743ddd8SMarcel Moolenaar# Program address of DMA memory 2668743ddd8SMarcel Moolenaarwrcsr(1, busaddr) 2678743ddd8SMarcel Moolenaarwrcsr(2, busaddr >> 16) 2688743ddd8SMarcel Moolenaardelay(100) 2698743ddd8SMarcel Moolenaar 2708743ddd8SMarcel Moolenaar# Initialize hardware 2718743ddd8SMarcel Moolenaarwrcsr(0, 1) 2728743ddd8SMarcel Moolenaarlogging.debug('Waiting for initialization to complete') 2738743ddd8SMarcel Moolenaarcsr = rdcsr(0) 2748743ddd8SMarcel Moolenaarwhile (csr & 0x100) == 0: 2758743ddd8SMarcel Moolenaar logging.debug('CSR=%#x' % (csr)) 2768743ddd8SMarcel Moolenaar csr = rdcsr(0) 2778743ddd8SMarcel Moolenaar 2788743ddd8SMarcel Moolenaarstart() 2798743ddd8SMarcel Moolenaar 2808743ddd8SMarcel Moolenaarpkt = packet.from_address(addr_txbufs) 2818743ddd8SMarcel Moolenaarctypes.memset(addr_txbufs, 0, ctypes.sizeof(pkt)) 2828743ddd8SMarcel Moolenaaroptions = [53, 1, 1] 283*da4f5bdaSMarcel Moolenaarfor i in range(len(options)): 2848743ddd8SMarcel Moolenaar pkt.dhcp_options[i] = options[i] 2858743ddd8SMarcel Moolenaarpkt.dhcp_magic = 0x63825363 286*da4f5bdaSMarcel Moolenaarfor i in range(6): 2878743ddd8SMarcel Moolenaar pkt.bootp_chaddr[i] = mac[i] 2888743ddd8SMarcel Moolenaarpkt.bootp_hlen = 6 2898743ddd8SMarcel Moolenaarpkt.bootp_htype = 1 2908743ddd8SMarcel Moolenaarpkt.bootp_op = 1 2918743ddd8SMarcel Moolenaarpkt.udp_len = ctypes.sizeof(pkt) - 34 2928743ddd8SMarcel Moolenaarpkt.udp_dest = 67 2938743ddd8SMarcel Moolenaarpkt.udp_src = 68 2948743ddd8SMarcel Moolenaarpkt.ip_dest = 0xffffffff 2958743ddd8SMarcel Moolenaarpkt.ip_cksum = 0x79a6 2968743ddd8SMarcel Moolenaarpkt.ip_proto = 17 2978743ddd8SMarcel Moolenaarpkt.ip_ttl = 64 2988743ddd8SMarcel Moolenaarpkt.ip_len = ctypes.sizeof(pkt) - 14 2998743ddd8SMarcel Moolenaarpkt.ip_vl = 0x45 3008743ddd8SMarcel Moolenaarpkt.eth_type = 0x0800 301*da4f5bdaSMarcel Moolenaarfor i in range(6): 3028743ddd8SMarcel Moolenaar pkt.eth_src[i] = mac[i] 3038743ddd8SMarcel Moolenaar pkt.eth_dest[i] = bcast[i] 3048743ddd8SMarcel Moolenaarpktlen = ctypes.sizeof(pkt) 3058743ddd8SMarcel Moolenaar 3068743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_txbufs - cpuaddr, bufsize) 3078743ddd8SMarcel Moolenaar 3088743ddd8SMarcel Moolenaarbd = bufdesc.from_address(addr_txdesc) 3098743ddd8SMarcel Moolenaarbd.length = 0 3108743ddd8SMarcel Moolenaarbd.flags = (1 << 31) | (1 << 25) | (1 << 24) | (0xf << 12) | (-pktlen & 0xfff) 3118743ddd8SMarcel Moolenaar 3128743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_txdesc - cpuaddr, 3138743ddd8SMarcel Moolenaar ctypes.sizeof(bufdesc)) 3148743ddd8SMarcel Moolenaar 3158743ddd8SMarcel Moolenaarwrcsr(0, 0x48) 3168743ddd8SMarcel Moolenaar 3178743ddd8SMarcel Moolenaarlogging.info('DHCP discovery packet sent') 3188743ddd8SMarcel Moolenaar 3198743ddd8SMarcel Moolenaar# Now wait 2 seconds for a DHCP offer to be received. 3208743ddd8SMarcel Moolenaarlogging.debug('Waiting 2 seconds for an offer to be received') 3218743ddd8SMarcel Moolenaartime.sleep(2) 3228743ddd8SMarcel Moolenaar 3238743ddd8SMarcel Moolenaarstop() 3248743ddd8SMarcel Moolenaar 3258743ddd8SMarcel Moolenaarbusdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_rxdesc - cpuaddr, 3268743ddd8SMarcel Moolenaar ctypes.sizeof(bufdesc) * nrxbufs) 3278743ddd8SMarcel Moolenaar 328*da4f5bdaSMarcel Moolenaarfor i in range(nrxbufs): 3298743ddd8SMarcel Moolenaar bd = bufdesc.from_address(addr_rxdesc + ctypes.sizeof(bufdesc) * i) 3308743ddd8SMarcel Moolenaar if (bd.flags & 0x80000000): 3318743ddd8SMarcel Moolenaar continue 3328743ddd8SMarcel Moolenaar pkt = packet.from_address(addr_rxbufs + i * bufsize) 3338743ddd8SMarcel Moolenaar if mac_is(pkt.eth_dest, bcast): 3348743ddd8SMarcel Moolenaar logging.debug('RX #%d: broadcast packet: length %u' % (i, bd.length)) 3358743ddd8SMarcel Moolenaar continue 3368743ddd8SMarcel Moolenaar if not mac_is(pkt.eth_dest, mac): 3378743ddd8SMarcel Moolenaar logging.debug('RX #%d: packet for %s?' % (i, mac_str(pkt.eth_dest))) 3388743ddd8SMarcel Moolenaar continue 3398743ddd8SMarcel Moolenaar logging.debug('RX %d: packet from %s!' % (i, mac_str(pkt.eth_src))) 3408743ddd8SMarcel Moolenaar logging.info('Our IP address = %s' % (ip_str(pkt.ip_dest))) 3418743ddd8SMarcel Moolenaar 3428743ddd8SMarcel Moolenaarbusdma.mem_free(dmamem) 3438743ddd8SMarcel Moolenaarbusdma.tag_destroy(mem_tag) 3448743ddd8SMarcel Moolenaarbus.unmap(io) 345