From owner-svn-src-all@FreeBSD.ORG Thu Nov 8 18:07:30 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4B87E772; Thu, 8 Nov 2012 18:07:30 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 30DC88FC16; Thu, 8 Nov 2012 18:07:30 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qA8I7UiU035510; Thu, 8 Nov 2012 18:07:30 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qA8I7UQs035508; Thu, 8 Nov 2012 18:07:30 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201211081807.qA8I7UQs035508@svn.freebsd.org> From: Adrian Chadd Date: Thu, 8 Nov 2012 18:07:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r242781 - head/sys/dev/ath X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Nov 2012 18:07:30 -0000 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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