- Add noise floor in ieee80211_nodestats; return it as zero until we can
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 25 Nov 2006 05:04:23 +0000 (05:04 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 25 Nov 2006 05:04:23 +0000 (05:04 +0000)
  update the api's so the driver can provide noise floor data
- Add a bandaid so IEEE80211_IOC_STA_STATS works for sta mode; when all
  nodes are in the station table this will no longer be needed
- Fix braino in IEEE80211_IOC_STA_INFO implementation; was supposed to
  take a MAC address and return info for that sta or all stations if
  ff:ff:ff:ff:ff was supplied -- but somehow this didn't get implemented;
  implement the intended semantics

Obtained-from: FreeBSD (sam@freebsd.org)

# NOTE: The RSSI statistics in ieee80211_nodestats is still unsigned

sys/netproto/802_11/ieee80211_ioctl.h
sys/netproto/802_11/wlan/ieee80211_ioctl.c

index 2ba8cf1..9ee0b46 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_ioctl.h,v 1.10.2.4 2005/12/22 19:18:23 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/ieee80211_ioctl.h,v 1.3 2006/09/01 15:12:11 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/ieee80211_ioctl.h,v 1.4 2006/11/25 05:04:23 sephe Exp $
  */
 #ifndef _NET80211_IEEE80211_IOCTL_H_
 #define _NET80211_IEEE80211_IOCTL_H_
@@ -43,7 +43,7 @@
 #include <netproto/802_11/ieee80211_crypto.h>
 
 /*
- * Per/node (station) statistics available when operating as an AP.
+ * Per/node (station) statistics.
  */
 struct ieee80211_nodestats {
        uint32_t        ns_rx_data;             /* rx data frames */
@@ -309,7 +309,7 @@ struct ieee80211req_sta_info {
        uint16_t        isi_flags;              /* channel flags */
        uint16_t        isi_state;              /* state flags */
        uint8_t         isi_authmode;           /* authentication algorithm */
-       uint8_t         isi_rssi;
+       uint8_t         isi_rssi;               /* receive signal strength */
        uint8_t         isi_capinfo;            /* capabilities */
        uint8_t         isi_erp;                /* ERP element */
        uint8_t         isi_macaddr[IEEE80211_ADDR_LEN];
@@ -317,6 +317,7 @@ struct ieee80211req_sta_info {
                                        /* negotiated rates */
        uint8_t         isi_rates[IEEE80211_RATE_MAXSIZE];
        uint8_t         isi_txrate;             /* index to isi_rates[] */
+       int8_t          isi_noise;              /* noise floor */
        uint16_t        isi_ie_len;             /* IE length */
        uint16_t        isi_associd;            /* assoc response */
        uint16_t        isi_txpower;            /* current tx power */
@@ -431,7 +432,6 @@ struct ieee80211req {
 #define        IEEE80211_IOC_CHANINFO          42      /* channel info list */
 #define        IEEE80211_IOC_TXPOWMAX          43      /* max tx power for channel */
 #define        IEEE80211_IOC_STA_TXPOW         44      /* per-station tx power limit */
-#define        IEEE80211_IOC_STA_INFO          45      /* station/neighbor info */
 #define        IEEE80211_IOC_WME_CWMIN         46      /* WME: ECWmin */
 #define        IEEE80211_IOC_WME_CWMAX         47      /* WME: ECWmax */
 #define        IEEE80211_IOC_WME_AIFS          48      /* WME: AIFSN */
@@ -446,6 +446,7 @@ struct ieee80211req {
 #define        IEEE80211_IOC_MCAST_RATE        72      /* tx rate for mcast frames */
 #define        IEEE80211_IOC_FRAGTHRESHOLD     73      /* tx fragmentation threshold */
 #define        IEEE80211_IOC_BURST             75      /* packet bursting */
+#define IEEE80211_IOC_STA_INFO         78      /* station/neighbor info */
 #define IEEE80211_IOC_RATECTL          255
 
 /*
index a588749..1b34b69 100644 (file)
@@ -30,7 +30,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net80211/ieee80211_ioctl.c,v 1.25.2.12 2006/04/03 17:21:05 sam Exp $
- * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ioctl.c,v 1.6 2006/11/23 13:43:05 sephe Exp $
+ * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ioctl.c,v 1.7 2006/11/25 05:04:23 sephe Exp $
  */
 
 /*
@@ -965,8 +965,12 @@ ieee80211_ioctl_getstastats(struct ieee80211com *ic, struct ieee80211req *ireq)
        if (error != 0)
                return error;
        ni = ieee80211_find_node(&ic->ic_sta, macaddr);
-       if (ni == NULL)
-               return EINVAL;          /* XXX */
+       if (ni == NULL) {
+               /* XXX special-case sta-mode until bss is node in ic_sta */
+               if (ic->ic_opmode != IEEE80211_M_STA)
+                       return ENOENT;
+               ni = ieee80211_ref_node(ic->ic_bss);
+       }
        if (ireq->i_len > sizeof(struct ieee80211req_sta_stats))
                ireq->i_len = sizeof(struct ieee80211req_sta_stats);
        /* NB: copy out only the statistics */
@@ -1121,6 +1125,7 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
        si->isi_state = ni->ni_flags;
        si->isi_authmode = ni->ni_authmode;
        si->isi_rssi = ic->ic_node_getrssi(ni);
+       si->isi_noise = 0;      /* XXX */
        si->isi_capinfo = ni->ni_capinfo;
        si->isi_erp = ni->ni_erp;
        IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr);
@@ -1165,15 +1170,34 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
 static int
 ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
 {
+       uint8_t macaddr[IEEE80211_ADDR_LEN];
+       const int off = __offsetof(struct ieee80211req_sta_req, info);
+       struct ieee80211_node *ni;
        struct stainforeq req;
        int error;
 
-       if (ireq->i_len < sizeof(struct stainforeq))
+       if (ireq->i_len < sizeof(struct ieee80211req_sta_req))
                return EFAULT;
+       error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
+       if (error != 0)
+               return error;
+       if (IEEE80211_ADDR_EQ(macaddr, ic->ic_ifp->if_broadcastaddr)) {
+               ni = NULL;
+       } else {
+               ni = ieee80211_find_node(&ic->ic_sta, macaddr);
+               if (ni == NULL) {
+                       /* XXX special-case sta-mode until bss is in ic_sta */
+                       if (ic->ic_opmode != IEEE80211_M_STA)
+                               return EINVAL;          /* XXX */
+                       ni = ieee80211_ref_node(ic->ic_bss);
+               }
+       }
 
-       error = 0;
        req.space = 0;
-       ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req);
+       if (ni == NULL)
+               ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req);
+       else
+               get_sta_space(&req, ni);
        if (req.space > ireq->i_len)
                req.space = ireq->i_len;
        if (req.space > 0) {
@@ -1183,16 +1207,24 @@ ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
                space = req.space;
                /* XXX M_WAITOK after driver lock released */
                p = kmalloc(space, M_TEMP, M_NOWAIT);
-               if (p == NULL)
-                       return ENOMEM;
+               if (p == NULL) {
+                       error = ENOMEM;
+                       goto bad;
+               }
                req.si = p;
-               ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req);
+               if (ni == NULL)
+                       ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req);
+               else
+                       get_sta_info(&req, ni);
                ireq->i_len = space - req.space;
-               error = copyout(p, ireq->i_data, ireq->i_len);
+               error = copyout(p, (uint8_t *)ireq->i_data + off, ireq->i_len);
                kfree(p, M_TEMP);
-       } else
+       } else {
                ireq->i_len = 0;
-
+       }
+bad:
+       if (ni != NULL)
+               ieee80211_free_node(ni);
        return error;
 }