<commit_before>/*	$OpenBSD: if_qe.c,v 1.32 2015/05/13 10:42:46 jsg Exp $	*/
/*      $NetBSD: if_qe.c,v 1.51 2002/06/08 12:28:37 ragge Exp $ */
/*
 * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed at Ludd, University of 
 *      Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Driver for DEQNA/DELQA ethernet cards.
 * Things that is still to do:
 *	Handle ubaresets. Does not work at all right now.
 *	Fix ALLMULTI reception. But someone must tell me how...
 *	Collect statistics.
 */

#include "bpfilter.h"

#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/sockio.h>

#include <net/if.h>
#include <net/if_dl.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>

#if NBPFILTER > 0
#include <net/bpf.h>
#include <net/bpfdesc.h>
#endif

#include <machine/bus.h>

#include <arch/vax/qbus/ubavar.h>
#include <arch/vax/if/if_qereg.h>

#define RXDESCS	30	/* # of receive descriptors */
#define TXDESCS	60	/* # transmit descs */

/*
 * Structure containing the elements that must be in DMA-safe memory.
 */
struct qe_cdata {
	struct qe_ring	qc_recv[RXDESCS+1];	/* Receive descriptors */
	struct qe_ring	qc_xmit[TXDESCS+1];	/* Transmit descriptors */
	u_int8_t	qc_setup[128];		/* Setup packet layout */
};

struct	qe_softc {
	struct device	sc_dev;		/* Configuration common part	*/
	struct evcount	sc_intrcnt;	/* Interrupt counting		*/
	int		sc_cvec;
	struct arpcom	sc_ac;		/* Ethernet common part		*/
#define sc_if	sc_ac.ac_if		/* network-visible interface	*/
	bus_space_tag_t sc_iot;
	bus_addr_t	sc_ioh;
	bus_dma_tag_t	sc_dmat;
	struct qe_cdata *sc_qedata;	/* Descriptor struct		*/
	struct qe_cdata *sc_pqedata;	/* Unibus address of above	*/
	struct mbuf*	sc_txmbuf[TXDESCS];
	struct mbuf*	sc_rxmbuf[RXDESCS];
	bus_dmamap_t	sc_xmtmap[TXDESCS];
	bus_dmamap_t	sc_rcvmap[RXDESCS];
	struct ubinfo	sc_ui;
	int		sc_intvec;	/* Interrupt vector		*/
	int		sc_nexttx;
	int		sc_inq;
	int		sc_lastack;
	int		sc_nextrx;
	int		sc_setup;	/* Setup packet in queue	*/
};

static	int	qematch(struct device *, struct cfdata *, void *);
static	void	qeattach(struct device *, struct device *, void *);
static	void	qeinit(struct qe_softc *);
static	void	qestart(struct ifnet *);
static	void	qeintr(void *);
static	int	qeioctl(struct ifnet *, u_long, caddr_t);
static	int	qe_add_rxbuf(struct qe_softc *, int);
static	void	qe_setup(struct qe_softc *);
static	void	qetimeout(struct ifnet *);

struct	cfattach qe_ca = {
	sizeof(struct qe_softc), (cfmatch_t)qematch, qeattach
};

struct cfdriver qe_cd = {
	NULL, "qe", DV_IFNET
};

#define	QE_WCSR(csr, val) \
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
#define	QE_RCSR(csr) \
	bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)

#define	LOWORD(x)	((int)(x) & 0xffff)
#define	HIWORD(x)	(((int)(x) >> 16) & 0x3f)

/*
 * Check for present DEQNA. Done by sending a fake setup packet
 * and wait for interrupt.
 */
int
qematch(struct device *parent, struct cfdata *cf, void *aux)
{
	struct	qe_softc ssc;
	struct	qe_softc *sc = &ssc;
	struct	uba_attach_args *ua = aux;
	struct	uba_softc *ubasc = (struct uba_softc *)parent;
	struct ubinfo ui;

#define	PROBESIZE	4096
	struct qe_ring *ring;
	struct	qe_ring *rp;
	int error;

	ring = malloc(PROBESIZE, M_TEMP, M_WAITOK | M_ZERO);
	bzero(sc, sizeof(struct qe_softc));
	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	ubasc->uh_lastiv -= 4;
	QE_WCSR(QE_CSR_CSR, QE_RESET);
	QE_WCSR(QE_CSR_VECTOR, ubasc->uh_lastiv);

	/*
	 * Map the ring area. Actually this is done only to be able to 
	 * send and receive a internal packet; some junk is loopbacked
	 * so that the DEQNA has a reason to interrupt.
	 */
	ui.ui_size = PROBESIZE;
	ui.ui_vaddr = (caddr_t)&ring[0];
	if ((error = uballoc((void *)parent, &ui, UBA_CANTWAIT)))
		return 0;

	/*
	 * Init a simple "fake" receive and transmit descriptor that
	 * points to some unused area. Send a fake setup packet.
	 */
	rp = (void *)ui.ui_baddr;
	ring[0].qe_flag = ring[0].qe_status1 = QE_NOTYET;
	ring[0].qe_addr_lo = LOWORD(&rp[4]);
	ring[0].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID | QE_EOMSG | QE_SETUP;
	ring[0].qe_buf_len = -64;

	ring[2].qe_flag = ring[2].qe_status1 = QE_NOTYET;
	ring[2].qe_addr_lo = LOWORD(&rp[4]);
	ring[2].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID;
	ring[2].qe_buf_len = -(1500/2);

	QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET);
	DELAY(1000);

	/*
	 * Start the interface and wait for the packet.<commit_msg>Memory leak in attach if uballoc() fails; Brainy/<NAME><commit_after>/*	$OpenBSD: if_qe.c,v 1.33 2015/06/27 15:39:03 miod Exp $	*/
/*      $NetBSD: if_qe.c,v 1.51 2002/06/08 12:28:37 ragge Exp $ */
/*
 * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed at Ludd, University of 
 *      Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Driver for DEQNA/DELQA ethernet cards.
 * Things that is still to do:
 *	Handle ubaresets. Does not work at all right now.
 *	Fix ALLMULTI reception. But someone must tell me how...
 *	Collect statistics.
 */

#include "bpfilter.h"

#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/sockio.h>

#include <net/if.h>
#include <net/if_dl.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>

#if NBPFILTER > 0
#include <net/bpf.h>
#include <net/bpfdesc.h>
#endif

#include <machine/bus.h>

#include <arch/vax/qbus/ubavar.h>
#include <arch/vax/if/if_qereg.h>

#define RXDESCS	30	/* # of receive descriptors */
#define TXDESCS	60	/* # transmit descs */

/*
 * Structure containing the elements that must be in DMA-safe memory.
 */
struct qe_cdata {
	struct qe_ring	qc_recv[RXDESCS+1];	/* Receive descriptors */
	struct qe_ring	qc_xmit[TXDESCS+1];	/* Transmit descriptors */
	u_int8_t	qc_setup[128];		/* Setup packet layout */
};

struct	qe_softc {
	struct device	sc_dev;		/* Configuration common part	*/
	struct evcount	sc_intrcnt;	/* Interrupt counting		*/
	int		sc_cvec;
	struct arpcom	sc_ac;		/* Ethernet common part		*/
#define sc_if	sc_ac.ac_if		/* network-visible interface	*/
	bus_space_tag_t sc_iot;
	bus_addr_t	sc_ioh;
	bus_dma_tag_t	sc_dmat;
	struct qe_cdata *sc_qedata;	/* Descriptor struct		*/
	struct qe_cdata *sc_pqedata;	/* Unibus address of above	*/
	struct mbuf*	sc_txmbuf[TXDESCS];
	struct mbuf*	sc_rxmbuf[RXDESCS];
	bus_dmamap_t	sc_xmtmap[TXDESCS];
	bus_dmamap_t	sc_rcvmap[RXDESCS];
	struct ubinfo	sc_ui;
	int		sc_intvec;	/* Interrupt vector		*/
	int		sc_nexttx;
	int		sc_inq;
	int		sc_lastack;
	int		sc_nextrx;
	int		sc_setup;	/* Setup packet in queue	*/
};

static	int	qematch(struct device *, struct cfdata *, void *);
static	void	qeattach(struct device *, struct device *, void *);
static	void	qeinit(struct qe_softc *);
static	void	qestart(struct ifnet *);
static	void	qeintr(void *);
static	int	qeioctl(struct ifnet *, u_long, caddr_t);
static	int	qe_add_rxbuf(struct qe_softc *, int);
static	void	qe_setup(struct qe_softc *);
static	void	qetimeout(struct ifnet *);

struct	cfattach qe_ca = {
	sizeof(struct qe_softc), (cfmatch_t)qematch, qeattach
};

struct cfdriver qe_cd = {
	NULL, "qe", DV_IFNET
};

#define	QE_WCSR(csr, val) \
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
#define	QE_RCSR(csr) \
	bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)

#define	LOWORD(x)	((int)(x) & 0xffff)
#define	HIWORD(x)	(((int)(x) >> 16) & 0x3f)

/*
 * Check for present DEQNA. Done by sending a fake setup packet
 * and wait for interrupt.
 */
int
qematch(struct device *parent, struct cfdata *cf, void *aux)
{
	struct	qe_softc ssc;
	struct	qe_softc *sc = &ssc;
	struct	uba_attach_args *ua = aux;
	struct	uba_softc *ubasc = (struct uba_softc *)parent;
	struct ubinfo ui;

#define	PROBESIZE	4096
	struct qe_ring *ring;
	struct	qe_ring *rp;
	int error;

	ring = malloc(PROBESIZE, M_TEMP, M_WAITOK | M_ZERO);
	bzero(sc, sizeof(struct qe_softc));
	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	ubasc->uh_lastiv -= 4;
	QE_WCSR(QE_CSR_CSR, QE_RESET);
	QE_WCSR(QE_CSR_VECTOR, ubasc->uh_lastiv);

	/*
	 * Map the ring area. Actually this is done only to be able to 
	 * send and receive a internal packet; some junk is loopbacked
	 * so that the DEQNA has a reason to interrupt.
	 */
	ui.ui_size = PROBESIZE;
	ui.ui_vaddr = (caddr_t)&ring[0];
	if ((error = uballoc((void *)parent, &ui, UBA_CANTWAIT))) {
		free(ring, M_TEMP, PROBESIZE);
		return 0;
	}

	/*
	 * Init a simple "fake" receive and transmit descriptor that
	 * points to some unused area. Send a fake setup packet.
	 */
	rp = (void *)ui.ui_baddr;
	ring[0].qe_flag = ring[0].qe_status1 = QE_NOTYET;
	ring[0].qe_addr_lo = LOWORD(&rp[4]);
	ring[0].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID | QE_EOMSG | QE_SETUP;
	ring[0].qe_buf_len = -64;

	ring[2].qe_flag = ring[2].qe_status1 = QE_NOTYET;
	ring[2].qe_addr_lo = LOWORD(&rp[4]);
	ring[2].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID;
	ring[2].qe_buf_len = -(1500/2);

	QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET);
	DELAY(1000);

	/*
	 * Start the interface and wait for the packet.
{'fraction_non_alphanumeric': 0.1115658508635508, 'fraction_numerical': 0.01538839322255873, 'mean_word_length': 4.1661733615221985, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5857767', 'n_tokens_mistral': 4881, 'n_tokens_neox': 4585, 'n_words': 1393}