Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Nov 2012 18:07:30 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r242781 - head/sys/dev/ath
Message-ID:  <201211081807.qA8I7UQs035508@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu Nov  8 18:07:29 2012
New Revision: 242781
URL: http://svnweb.freebsd.org/changeset/base/242781

Log:
  Add my initial cut at driver-layer ALQ support.
  
  I'm using this to debug EDMA TX and RX descriptors and it's really helpful
  to have a non-printf() way to decode frames.
  
  I won't link this into the build until I've tidied it up a little more.
  
  This will eventually be behind ATH_DEBUG_ALQ.

Added:
  head/sys/dev/ath/if_ath_alq.c   (contents, props changed)
  head/sys/dev/ath/if_ath_alq.h   (contents, props changed)

Added: head/sys/dev/ath/if_ath_alq.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ath/if_ath_alq.c	Thu Nov  8 18:07:29 2012	(r242781)
@@ -0,0 +1,172 @@
+/*-
+ * Copyright (c) 2012 Adrian Chadd
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+#include "opt_ath.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/alq.h>
+
+#include <dev/ath/if_ath_alq.h>
+
+#ifdef	ATH_DEBUG_ALQ
+static struct ale *
+if_ath_alq_get(struct if_ath_alq *alq, int len)
+{
+	struct ale *ale;
+
+	if (alq->sc_alq_isactive == 0)
+		return (NULL);
+
+	ale = alq_getn(alq->sc_alq_alq, len, ALQ_NOWAIT);
+	if (! ale)
+		alq->sc_alq_numlost++;
+	return (ale);
+}
+
+void
+if_ath_alq_init(struct if_ath_alq *alq, const char *devname)
+{
+
+	bzero(alq, sizeof(*alq));
+
+	strncpy(alq->sc_alq_devname, devname, ATH_ALQ_DEVNAME_LEN);
+	printf("%s (%s): detached\n", __func__, alq->sc_alq_devname);
+	snprintf(alq->sc_alq_filename, ATH_ALQ_FILENAME_LEN,
+	    "/tmp/ath_%s_alq.log", alq->sc_alq_devname);
+
+	/* XXX too conservative, right? */
+	alq->sc_alq_qsize = (64*1024);
+}
+
+void
+if_ath_alq_tidyup(struct if_ath_alq *alq)
+{
+
+	if_ath_alq_stop(alq);
+	printf("%s (%s): detached\n", __func__, alq->sc_alq_devname);
+	bzero(alq, sizeof(*alq));
+}
+
+int
+if_ath_alq_start(struct if_ath_alq *alq)
+{
+	int error;
+
+	if (alq->sc_alq_isactive)
+		return (0);
+
+	/*
+	 * Create a variable-length ALQ.
+	 */
+	error = alq_open(&alq->sc_alq_alq, alq->sc_alq_filename,
+	    curthread->td_ucred, ALQ_DEFAULT_CMODE,
+	    alq->sc_alq_qsize, 0);
+
+	if (error != 0) {
+		printf("%s (%s): failed, err=%d\n", __func__,
+		    alq->sc_alq_devname, error);
+	} else {
+		printf("%s (%s): opened\n", __func__, alq->sc_alq_devname);
+		alq->sc_alq_isactive = 1;
+	}
+	return (error);
+}
+
+int
+if_ath_alq_stop(struct if_ath_alq *alq)
+{
+
+	if (alq->sc_alq_isactive == 0)
+		return (0);
+
+	printf("%s (%s): closed\n", __func__, alq->sc_alq_devname);
+
+	alq->sc_alq_isactive = 0;
+	alq_close(alq->sc_alq_alq);
+	alq->sc_alq_alq = NULL;
+
+	return (0);
+}
+
+/*
+ * Post a debug message to the ALQ.
+ *
+ * "len" is the size of the buf payload in bytes.
+ */
+void
+if_ath_alq_post(struct if_ath_alq *alq, uint16_t op, uint16_t len,
+    const char *buf)
+{
+	struct if_ath_alq_hdr *ap;
+	struct ale *ale;
+
+	if (! if_ath_alq_checkdebug(alq, op))
+		return;
+
+	/*
+	 * Enforce some semblence of sanity on 'len'.
+	 * Although strictly speaking, any length is possible -
+	 * just be conservative so things don't get out of hand.
+	 */
+	if (len > ATH_ALQ_PAYLOAD_LEN)
+		len = ATH_ALQ_PAYLOAD_LEN;
+
+	ale = if_ath_alq_get(alq, len + sizeof(struct if_ath_alq_hdr));
+
+	if (ale == NULL)
+		return;
+
+	ap = (struct if_ath_alq_hdr *) ale->ae_data;
+	ap->threadid = (uint64_t) curthread->td_tid;
+	ap->tstamp = (uint32_t) ticks;
+	ap->op = op;
+	ap->len = len;
+
+	/*
+	 * Copy the payload _after_ the header field.
+	 */
+	memcpy(((char *) ap) + sizeof(struct if_ath_alq_hdr),
+	    buf,
+	    ap->len);
+
+	alq_post(alq->sc_alq_alq, ale);
+}
+#endif	/* ATH_DEBUG */

Added: head/sys/dev/ath/if_ath_alq.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ath/if_ath_alq.h	Thu Nov  8 18:07:29 2012	(r242781)
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2012 Adrian Chadd
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#ifndef	__IF_ATH_ALQ_H__
+#define	__IF_ATH_ALQ_H__
+
+#define	ATH_ALQ_FILENAME_LEN	128
+#define	ATH_ALQ_DEVNAME_LEN	32
+
+struct if_ath_alq {
+	uint32_t	sc_alq_debug;		/* Debug flags to report */
+	struct alq *	sc_alq_alq;		/* alq state */
+	unsigned int	sc_alq_qsize;		/* queue size */
+	unsigned int	sc_alq_numlost;		/* number of "lost" entries */
+	int		sc_alq_isactive;
+	char		sc_alq_devname[ATH_ALQ_DEVNAME_LEN];
+	char		sc_alq_filename[ATH_ALQ_FILENAME_LEN];
+};
+
+#define	ATH_ALQ_EDMA_TXSTATUS		1
+#define	ATH_ALQ_EDMA_RXSTATUS		2
+#define	ATH_ALQ_EDMA_TXDESC		3
+
+/* 128 bytes in total */
+#define	ATH_ALQ_PAYLOAD_LEN		112
+
+struct if_ath_alq_hdr {
+	uint64_t	threadid;
+	uint32_t	tstamp;
+	uint16_t	op;
+	uint16_t	len;	/* Length of (optional) payload */
+};
+
+struct if_ath_alq_payload {
+	struct if_ath_alq_hdr hdr;
+	char		payload[];
+};
+
+#ifdef	_KERNEL
+static inline int
+if_ath_alq_checkdebug(struct if_ath_alq *alq, uint16_t op)
+{
+
+	return (alq->sc_alq_debug & (1 << (op - 1)));
+}
+
+extern	void if_ath_alq_init(struct if_ath_alq *alq, const char *devname);
+extern	void if_ath_alq_tidyup(struct if_ath_alq *alq);
+extern	int if_ath_alq_start(struct if_ath_alq *alq);
+extern	int if_ath_alq_stop(struct if_ath_alq *alq);
+extern	void if_ath_alq_post(struct if_ath_alq *alq, uint16_t op,
+	    uint16_t len, const char *buf);
+#endif	/* _KERNEL */
+
+#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211081807.qA8I7UQs035508>