Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Mar 2019 07:58:19 +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: r344842 - in head/tools/tools/ath: . athani
Message-ID:  <201903060758.x267wJcP073627@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Mar  6 07:58:19 2019
New Revision: 344842
URL: https://svnweb.freebsd.org/changeset/base/344842

Log:
  [athani] Add a simple tool to list and control ANI parameters.
  
  This is a WIP tool I'm using to figure out why ANI is weirdly busted in my
  home FreeBSD AP/STA setup.  Although athstats (mostly) gets the ANI statistics
  correct, ANI is making the radio deaf it doesn't recover without being disabled.
  
  It's very WIP.
  
  Tested:
  
  * Carambola 2,  (AR9331), AP/STA mode.

Added:
  head/tools/tools/ath/athani/
  head/tools/tools/ath/athani/Makefile   (contents, props changed)
  head/tools/tools/ath/athani/main.c   (contents, props changed)
Modified:
  head/tools/tools/ath/Makefile

Modified: head/tools/tools/ath/Makefile
==============================================================================
--- head/tools/tools/ath/Makefile	Wed Mar  6 07:54:29 2019	(r344841)
+++ head/tools/tools/ath/Makefile	Wed Mar  6 07:58:19 2019	(r344842)
@@ -3,6 +3,6 @@
 SUBDIR=	arcode athdebug athdecode athkey athpoke athprom athrd athregs athalq
 SUBDIR+=	athstats ath_prom_read athradar athaggrstats
 SUBDIR+=	ath_ee_v14_print ath_ee_v4k_print ath_ee_9287_print ath_ee_9300_print
-SUBDIR+=	athsurvey athratestats athspectral
+SUBDIR+=	athsurvey athratestats athspectral athani
 
 .include <bsd.subdir.mk>

Added: head/tools/tools/ath/athani/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/ath/athani/Makefile	Wed Mar  6 07:58:19 2019	(r344842)
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+PROG=	athani
+MAN=
+
+CFLAGS+=	-I../../../../sys/contrib
+
+SRCS=	main.c
+
+.include <../Makefile.inc>
+
+CFLAGS+=	-I${.CURDIR}/../common/
+.PATH.c:	${.CURDIR}/../common/
+SRCS+=		ctrl.c
+
+CLEANFILES+=    opt_ah.h
+
+opt_ah.h:
+	echo "#define AH_DEBUG 1" > opt_ah.h
+	echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+	echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <bsd.prog.mk>

Added: head/tools/tools/ath/athani/main.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/ath/athani/main.c	Wed Mar  6 07:58:19 2019	(r344842)
@@ -0,0 +1,226 @@
+/*-
+ * Copyright (c) 2019 Adrian Chadd <adrian@FreeBSD.org>.
+ * 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 "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <err.h>
+
+#include "../common/ctrl.h"
+
+/*
+ * This is a simple wrapper program around the ANI diagnostic interface.
+ * It is for fetching and setting the live ANI configuration when trying
+ * to diagnose a noisy environment.
+ */
+
+/*
+ * HAL_DIAG_ANI_CMD is used to set the ANI configuration.
+ * HAL_DIAG_ANI_CURRENT is used to fetch the current ANI configuration.
+ */
+
+struct ani_var {
+  const char *name;
+  int id;
+};
+
+static struct ani_var ani_labels[] = {
+  { "ofdm_noise_immunity_level", 1, },
+  { "noise_immunity_level", 1, },
+  { "ofdm_weak_signal_detect", 2, },
+  { "cck_weak_signal_threshold", 3, },
+  { "firstep_level", 4, },
+  { "spur_immunity_level", 5, },
+  { "mrc_cck", 8, },
+  { "cck_noise_immunity_level", 9, },
+  { NULL, -1, },
+};
+
+static void
+usage(void)
+{
+	fprintf(stderr, "usage: athani [-i interface] [-l]\n");
+	fprintf(stderr, "    -i: interface\n");
+	fprintf(stderr, "    -l: list ANI labels\n");
+	fprintf(stderr, "  If no args are given after flags, the ANI state will be listed.\n");
+	fprintf(stderr, "  To set, use '<label> <value>' to set the state\n");
+	exit(-1);
+}
+
+static void
+list_labels(void)
+{
+	int i;
+
+	for (i = 0; ani_labels[i].name != NULL; i++) {
+		printf("%s (%d)\n", ani_labels[i].name, ani_labels[i].id);
+	}
+}
+
+static int
+ani_write_state(struct ath_driver_req *req, const char *ifname,
+  const char *label, const char *value)
+{
+	struct ath_diag atd;
+	uint32_t args[2];
+	uint32_t cmd, val;
+	size_t sl;
+	int i;
+
+	/* Find the label */
+	sl = strlen(label);
+	for (i = 0; ani_labels[i].name != NULL; i++) {
+		if ((strlen(ani_labels[i].name) == sl) &&
+		    (strcmp(label, ani_labels[i].name) == 0)) {
+			cmd = ani_labels[i].id;
+			break;
+		}
+	}
+	if (ani_labels[i].name == NULL) {
+		fprintf(stderr, "%s: couldn't find ANI label (%s)\n",
+		    __func__, label);
+		return (-1);
+	}
+
+	val = strtoul(value, NULL, 0);
+
+	/*
+	 * Whilst we're doing the ath_diag pieces, we have to set this
+	 * ourselves.
+	 */
+	strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+	/*
+	 * Populate HAL_DIAG_ANI_CMD fields.
+	 */
+	args[0] = cmd;
+	args[1] = val;
+
+	atd.ad_id = HAL_DIAG_ANI_CMD | ATH_DIAG_IN;
+	atd.ad_out_data = NULL;
+	atd.ad_out_size = 0;
+	atd.ad_in_data = (void *) &args;
+	atd.ad_in_size = sizeof(args);
+
+	if (ath_driver_req_fetch_diag(req, SIOCGATHDIAG, &atd) < 0) {
+		warn("SIOCGATHDIAG HAL_DIAG_ANI_CMD (%s)", atd.ad_name);
+		return (-1);
+	}
+
+	return (0);
+}
+
+static void
+ani_read_state(struct ath_driver_req *req, const char *ifname)
+{
+	struct ath_diag atd;
+	HAL_ANI_STATE state;
+
+	/*
+	 * Whilst we're doing the ath_diag pieces, we have to set this
+	 * ourselves.
+	 */
+	strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+	atd.ad_id = HAL_DIAG_ANI_CURRENT; /* XXX | DIAG_DYN? */
+	atd.ad_out_data = (caddr_t) &state;
+	atd.ad_out_size = sizeof(state);
+
+	if (ath_driver_req_fetch_diag(req, SIOCGATHDIAG, &atd) < 0)
+		err(1, "%s", atd.ad_name);
+
+
+	printf("  ofdm_noise_immunity_level=%d\n", state.noiseImmunityLevel);
+	printf("  cck_noise_immunity_level=%d\n", state.cckNoiseImmunityLevel);
+	printf("  spur_immunity_level=%d\n", state.spurImmunityLevel);
+	printf("  firstep_level=%d\n", state.firstepLevel);
+	printf("  ofdm_weak_signal_detect=%d\n", state.ofdmWeakSigDetectOff);
+	printf("  cck_weak_signal_threshold=%d\n", state.cckWeakSigThreshold);
+	printf("  mrc_cck=%d\n", state.mrcCckOff);
+	/* XXX TODO: cycle counts? */
+}
+
+int
+main(int argc, char *argv[])
+{
+	struct ath_diag atd;
+	const char *ifname;
+	struct ath_driver_req req;
+	int what, c;
+
+	ath_driver_req_init(&req);
+
+	ifname = getenv("ATH");
+	if (!ifname)
+		ifname = ATH_DEFAULT;
+
+	what = 0;
+	while ((c = getopt(argc, argv, "i:l")) != -1)
+		switch (c) {
+		case 'i':
+			ifname = optarg;
+			break;
+		case 'l':
+			list_labels();
+			exit(0);
+		default:
+			usage();
+			/*NOTREACHED*/
+		}
+
+	/* Initialise the driver interface */
+	if (ath_driver_req_open(&req, ifname) < 0) {
+		exit(127);
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc == 0) {
+		ani_read_state(&req, ifname);
+		exit(0);
+	}
+
+	if (argc < 2) {
+		usage();
+		/*NOTREACHED*/
+	}
+
+	if (ani_write_state(&req, ifname, argv[0], argv[1]) != 0)
+		exit(1);
+
+	exit(0);
+}



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