From a351ccac7b4fdc59bdb1eeb098f622c6ea99781a Mon Sep 17 00:00:00 2001 From: adrian Date: Sun, 28 Feb 2016 06:29:07 +0000 Subject: 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 --- tools/tools/ath/common/ctrl.c | 218 ++++++++++++++++++++++++++++++++++++++++++ tools/tools/ath/common/ctrl.h | 59 ++++++++++++ 2 files changed, 277 insertions(+) create mode 100644 tools/tools/ath/common/ctrl.c create mode 100644 tools/tools/ath/common/ctrl.h 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 . + * 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 . + * 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 -- cgit v1.1