diff options
author | adrian <adrian@FreeBSD.org> | 2016-02-28 06:29:07 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2016-02-28 06:29:07 +0000 |
commit | a351ccac7b4fdc59bdb1eeb098f622c6ea99781a (patch) | |
tree | 83b456f454ea7c4e2b536bd158bf2a96c254dd9f | |
parent | 3731504c28c2adc216a956e101fcd261c3b8b979 (diff) | |
download | FreeBSD-src-a351ccac7b4fdc59bdb1eeb098f622c6ea99781a.zip FreeBSD-src-a351ccac7b4fdc59bdb1eeb098f622c6ea99781a.tar.gz |
Begin abstracting out the access method for ath(4) ioctls.
Each of the ath* commands do their own direct socket/ioctl calls,
which makes it difficult to forklift upgrade things.
So, this is the beginning of abstracting out the stats API calls
in the hope that I can migrate things to use a /dev/athX file for
ioctls and use a more general interface.
Tested:
* QCA9565 NIC, STA mode
-rw-r--r-- | tools/tools/ath/common/ctrl.c | 218 | ||||
-rw-r--r-- | tools/tools/ath/common/ctrl.h | 59 |
2 files changed, 277 insertions, 0 deletions
diff --git a/tools/tools/ath/common/ctrl.c b/tools/tools/ath/common/ctrl.c new file mode 100644 index 0000000..e5de77d --- /dev/null +++ b/tools/tools/ath/common/ctrl.c @@ -0,0 +1,218 @@ +/*- + * Copyright (c) 2016 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$ + */ + +/* + * This is a simple abstraction of the control channel used to access + * device specific data. + * + * In the past it used a ifnet socket on athX, but since those devices + * are now gone, they can use wlanX. However, there are debug cases + * where you'll instead want to talk to the hardware before any VAPs are + * up, so we should also handle the case of talking to /dev/athX. + * + * For now this'll be a drop-in replacement for the existing ioctl() + * based method until the /dev/athX (and associated new ioctls) land + * in the tree. + */ + +#include <sys/param.h> +#include <sys/file.h> +#include <sys/sockio.h> +#include <sys/socket.h> + +#include <net/if.h> +#include <net/if_media.h> +#include <net/if_var.h> + +#include <err.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "ah.h" +#include "ah_desc.h" +#include "net80211/ieee80211_ioctl.h" +#include "net80211/ieee80211_radiotap.h" +#include "if_athioctl.h" +#include "if_athrate.h" + +#include "ctrl.h" + +int +ath_driver_req_init(struct ath_driver_req *req) +{ + + bzero(req, sizeof(*req)); + req->s = -1; + return (0); +} + +/* + * Open a suitable file descriptor and populate the relevant interface + * information for ioctls. + * + * For file path based access the ifreq isn't required; it'll just be + * a direct ioctl on the file descriptor. + */ +int +ath_driver_req_open(struct ath_driver_req *req, const char *ifname) +{ + int s; + + if (s != -1) + ath_driver_req_close(req); + + /* For now, netif socket, not /dev/ filedescriptor */ + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + warn("%s: socket", __func__); + return (-1); + } + req->ifname = strdup(ifname); + req->s = s; + + return (0); +} + +/* + * Close an open descriptor. + */ +int +ath_driver_req_close(struct ath_driver_req *req) +{ + if (req->s == -1) + return (0); + close(req->s); + free(req->ifname); + req->s = -1; + req->ifname = NULL; + return (0); +} + +/* + * Issue a diagnostic API request. + */ +int +ath_driver_req_fetch_diag(struct ath_driver_req *req, unsigned long cmd, + struct ath_diag *ad) +{ + int ret; + + ret = ioctl(req->s, cmd, ad); + if (ret < 0) + warn("%s: ioctl", __func__); + return (ret); +} + +/* + * Issue a zero statistics API request. + */ +int +ath_driver_req_zero_stats(struct ath_driver_req *req) +{ + struct ifreq ifr; + int ret; + + /* Setup ifreq */ + bzero(&ifr, sizeof(ifr)); + strncpy(ifr.ifr_name, req->ifname, sizeof (ifr.ifr_name)); + ifr.ifr_data = NULL; + + /* ioctl */ + ret = ioctl(req->s, SIOCZATHSTATS, &ifr); + if (ret < 0) + warn("%s: ioctl", __func__); + return (ret); +} + +/* + * Fetch general statistics. + */ +int +ath_driver_req_fetch_stats(struct ath_driver_req *req, struct ath_stats *st) +{ + struct ifreq ifr; + int ret; + + /* Setup ifreq */ + bzero(&ifr, sizeof(ifr)); + strncpy(ifr.ifr_name, req->ifname, sizeof (ifr.ifr_name)); + ifr.ifr_data = (caddr_t) st; + + /* ioctl */ + ret = ioctl(req->s, SIOCGATHSTATS, &ifr); + if (ret < 0) + warn("%s: ioctl", __func__); + return (ret); +} + +/* + * Fetch aggregate statistics. + */ +int +ath_drive_req_fetch_aggr_stats(struct ath_driver_req *req, + struct ath_tx_aggr_stats *tx) +{ + struct ifreq ifr; + int ret; + + /* Setup ifreq */ + bzero(&ifr, sizeof(ifr)); + strncpy(ifr.ifr_name, req->ifname, sizeof (ifr.ifr_name)); + ifr.ifr_data = (caddr_t) tx; + + /* ioctl */ + ret = ioctl(req->s, SIOCGATHAGSTATS, &ifr); + if (ret < 0) + warn("%s: ioctl", __func__); + return (ret); + +} + +/* + * Fetch rate control statistics. + * + * Caller has to populate the interface name and MAC address. + */ +int +ath_drive_req_fetch_ratectrl_stats(struct ath_driver_req *req, + struct ath_rateioctl *r) +{ + int ret; + + /* ioctl */ + ret = ioctl(req->s, SIOCGATHNODERATESTATS, r); + if (ret < 0) + warn("%s: ioctl", __func__); + return (ret); +} diff --git a/tools/tools/ath/common/ctrl.h b/tools/tools/ath/common/ctrl.h new file mode 100644 index 0000000..ca95e58 --- /dev/null +++ b/tools/tools/ath/common/ctrl.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2016 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$ + */ +#ifndef __ATH_CTRL_H__ +#define __ATH_CTRL_H__ + +struct ath_stats; +struct ath_diag; +struct ath_tx_aggr_stats; +struct ath_rateioctl; + +struct ath_driver_req { + /* Open socket, or -1 */ + int s; + /* The interface name in question */ + char *ifname; +}; + +extern int ath_driver_req_init(struct ath_driver_req *req); +extern int ath_driver_req_open(struct ath_driver_req *req, const char *ifname); +extern int ath_driver_req_close(struct ath_driver_req *req); +extern int ath_driver_req_fetch_diag(struct ath_driver_req *req, + unsigned long cmd, struct ath_diag *ad); +extern int ath_driver_req_zero_stats(struct ath_driver_req *req); +extern int ath_driver_req_fetch_stats(struct ath_driver_req *req, + struct ath_stats *st); +extern int ath_drive_req_fetch_aggr_stats(struct ath_driver_req *req, + struct ath_tx_aggr_stats *tx); +extern int ath_drive_req_fetch_ratectrl_stats(struct ath_driver_req *req, + struct ath_rateioctl *r); + +#endif |