summaryrefslogblamecommitdiffstats
path: root/bsps/powerpc/beatnik/net/if_mve/mve_smallbuf_tst.c
blob: 721ade30d1dcebca93c4d0719e83e3241077fb8e (plain) (tree)




























































                                                           
                      


















































































                                                                               
#include <rtems.h>
#include <bsp.h>
#include <bsp/if_mve_pub.h>
#include <stdlib.h>
#include <stdio.h>

/* Demo for the mv64360 ethernet quirk:
 *
 * $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 * $$ buffer segments < 8 bytes must be aligned $$
 * $$ to 8 bytes but larger segments are not    $$
 * $$ sensitive to alignment.                   $$
 * $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 *
 * How to use:
 *
 *   Init MVE driver on (unused) unit 2:
 *
 *    mve = mvtst_init(2)
 *
 *    data = { 1,2,3,4,5,6,7,8,9,0xa,0xb, ... }
 *
 *   Alloc 2-element mbuf chain (1st holds an
 *   ethernet header which is > 8bytes so we can't
 *   test this with only 1 mbuf. The 2nd mbuf holds
 *   a small fragment of data).
 *
 *     mb  = mvtst_getbuf(mve)
 *
 *   Copy data into aligned area inside 2nd mbuf,
 *   (so that you can see if the chip starts using
 *   the aligned area rather than the unaligned
 *   buffer pointer). Point mbuf's data pointer
 *   at 'off'set from the aligned area:
 *
 *     mvtst_putbuf(mb, data, len, offset)
 *
 *   Send chain off:
 *
 *    BSP_mve_send_buf(mve, mb, 0, 0)
 *
 *   Watch raw data:
 *
 *    tcpdump -XX -vv -s0 ether host <my-ether-addr>
 *
 *   E.g, if offset = 1, len = 2 then we would like
 *   to see 
 *  
 *   GOOD:
 *           < 14 header bytes > 0x02, 0x03

 *   but if the chip starts DMA at aligned address
 *   we see instead
 *   BAD:
 *           < 14 header bytes > 0x01, 0x02
 */

static inline void *rmalloc(size_t l) { return malloc(l); }
static inline void  rfree(void *p) { return free(p); }

#define _KERNEL
#include <sys/param.h>
#include <sys/mbuf.h>

static void
cleanup_buf(void *u_b, void *closure, int error)
{
rtems_bsdnet_semaphore_obtain();
	m_freem((struct mbuf*)u_b);
rtems_bsdnet_semaphore_release();
}

struct mbuf *mvtst_getbuf(struct mveth_private *mp)
{
struct mbuf *m,*n;

	if ( !mp ) {
		printf("need driver ptr arg\n");
		return 0;
	}
rtems_bsdnet_semaphore_obtain();
	MGETHDR(m, M_DONTWAIT, MT_DATA);
	MGET(n, M_DONTWAIT, MT_DATA);
	m->m_next = n;
rtems_bsdnet_semaphore_release();
	/* Ethernet header */
	memset( mtod(m, unsigned char*), 0xff, 6);
	BSP_mve_read_eaddr(mp, mtod(m, unsigned char*) + 6);
	/* Arbitrary; setting to IP but we don't bother
	 * to setup a real IP header. We just watch the
	 * raw packet contents...
	 */
	mtod(m, unsigned char*)[12] = 0x08;
	mtod(m, unsigned char*)[13] = 0x00;
	m->m_pkthdr.len = m->m_len = 14;
	n->m_len = 0;
	return m;
}

int
mvtst_putbuf(struct mbuf *m, void *data, int len, int off)
{
int i;
	if ( m ) {
		m->m_pkthdr.len += len;
	if ( ( m= m->m_next ) ) {
		m->m_len = len;
		memcpy(mtod(m, void*), data, 32);
		m->m_data += off;
		printf("m.dat: 0x%08x, m.data: 0x%08x\n", m->m_dat, m->m_data);
		for ( i=0; i< 16; i++ ) {
			printf(" %02x,",mtod(m, unsigned char*)[i]);
		}
		printf("\n");
	}
	}
	
	return 0;
}

static void *alloc_rxbuf(int *p_size, unsigned long *paddr)
{
	return *(void**)paddr = rmalloc((*p_size = 1800));
}

static void consume_buf(void *buf, void *closure, int len)
{
	rfree(buf);
}

void *
mvtst_init(int unit)
{
struct mveth_private *mp;
	mp = BSP_mve_setup(
		unit, 0,
		cleanup_buf, 0,
		alloc_rxbuf,
		consume_buf, 0,
		10, 10,
		0);
	if ( mp )
		BSP_mve_init_hw(mp, 0, 0);
	return mp;
}