xref: /freebsd/tools/bus_space/examples/am79c900_diag.py (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
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