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