Module Name:    src
Committed By:   jmcneill
Date:           Thu Oct  3 14:42:20 UTC 2019

Modified Files:
        src/sys/dev/ic: bwfm.c bwfmreg.h

Log Message:
If firmware is connected in HT or VHT mode, report it to SIOCGIFMEDIA


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/ic/bwfm.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/ic/bwfmreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/bwfm.c
diff -u src/sys/dev/ic/bwfm.c:1.16 src/sys/dev/ic/bwfm.c:1.17
--- src/sys/dev/ic/bwfm.c:1.16	Mon Sep  2 07:25:48 2019
+++ src/sys/dev/ic/bwfm.c	Thu Oct  3 14:42:20 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfm.c,v 1.16 2019/09/02 07:25:48 mlelstv Exp $ */
+/* $NetBSD: bwfm.c,v 1.17 2019/10/03 14:42:20 jmcneill Exp $ */
 /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -112,6 +112,7 @@ int	 bwfm_fwvar_var_set_int(struct bwfm_
 struct ieee80211_channel *bwfm_bss2chan(struct bwfm_softc *, struct bwfm_bss_info *);
 void	 bwfm_scan(struct bwfm_softc *);
 void	 bwfm_connect(struct bwfm_softc *);
+void	 bwfm_get_sta_info(struct bwfm_softc *, struct ifmediareq *);
 
 void	 bwfm_rx(struct bwfm_softc *, struct mbuf *);
 void	 bwfm_rx_event(struct bwfm_softc *, struct mbuf *);
@@ -512,6 +513,12 @@ bwfm_ioctl(struct ifnet *ifp, u_long cmd
 		}
 		break;
 
+	case SIOCGIFMEDIA:
+		error = ieee80211_ioctl(ic, cmd, data);
+		if (error == 0 && ic->ic_state == IEEE80211_S_RUN)
+			bwfm_get_sta_info(sc, (struct ifmediareq *)data);
+		break;
+
 	default:
 		error = ieee80211_ioctl(ic, cmd, data);
 	}
@@ -1789,6 +1796,50 @@ bwfm_connect(struct bwfm_softc *sc)
 }
 
 void
+bwfm_get_sta_info(struct bwfm_softc *sc, struct ifmediareq *ifmr)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ieee80211_node *ni = ic->ic_bss;
+	struct bwfm_sta_info sta;
+	uint32_t flags, txrate;
+
+	memset(&sta, 0, sizeof(sta));
+	memcpy(&sta, ni->ni_macaddr, sizeof(ni->ni_macaddr));
+
+	if (bwfm_fwvar_var_get_data(sc, "sta_info", &sta, sizeof(sta)))
+		return;
+
+	if (!IEEE80211_ADDR_EQ(ni->ni_macaddr, sta.ea))
+		return;
+
+	if (le16toh(sta.ver) < 4)
+		return;
+
+	flags = le32toh(sta.flags);
+	if ((flags & BWFM_STA_SCBSTATS) == 0)
+		return;
+
+	txrate = le32toh(sta.tx_rate);
+	if (txrate == 0xffffffff)
+		return;
+
+	if ((flags & BWFM_STA_VHT_CAP) != 0) {
+		ifmr->ifm_active &= ~IFM_TMASK;
+		ifmr->ifm_active |= IFM_IEEE80211_VHT;
+		ifmr->ifm_active &= ~IFM_MMASK;
+		ifmr->ifm_active |= IFM_IEEE80211_11AC;
+	} else if ((flags & BWFM_STA_N_CAP) != 0) {
+		ifmr->ifm_active &= ~IFM_TMASK;
+		ifmr->ifm_active |= IFM_IEEE80211_MCS;
+		ifmr->ifm_active &= ~IFM_MMASK;
+		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
+			ifmr->ifm_active |= IFM_IEEE80211_11NG;
+		else
+			ifmr->ifm_active |= IFM_IEEE80211_11NA;
+	}
+}
+
+void
 bwfm_rx(struct bwfm_softc *sc, struct mbuf *m)
 {
 	struct ieee80211com *ic = &sc->sc_ic;

Index: src/sys/dev/ic/bwfmreg.h
diff -u src/sys/dev/ic/bwfmreg.h:1.4 src/sys/dev/ic/bwfmreg.h:1.5
--- src/sys/dev/ic/bwfmreg.h:1.4	Sun Sep  1 05:40:39 2019
+++ src/sys/dev/ic/bwfmreg.h	Thu Oct  3 14:42:20 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfmreg.h,v 1.4 2019/09/01 05:40:39 mlelstv Exp $ */
+/* $NetBSD: bwfmreg.h,v 1.5 2019/10/03 14:42:20 jmcneill Exp $ */
 /* $OpenBSD: bwfmreg.h,v 1.16 2018/02/07 21:44:09 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
@@ -391,6 +391,137 @@ struct bwfm_bss_info {
 	uint16_t snr;
 };
 
+#define BWFM_MAXRATES_IN_SET		BWFM_MCSSET_LEN
+#define BWFM_ANT_MAX			4
+#define BWFM_VHT_CAP_MCS_MAP_NSS_MAX	8
+#define BWFM_HE_CAP_MCS_MAP_NSS_MAX	BWFM_VHT_CAP_MCS_MAP_NSS_MAX
+
+struct bwfm_sta_rateset_v5 {
+	uint32_t count;
+	/* rates in 500kbps units w/hi bit set if basic */
+	uint8_t rates[BWFM_MAXRATES_IN_SET];
+	uint8_t mcs[BWFM_MCSSET_LEN];
+	uint16_t vht_mcs[BWFM_VHT_CAP_MCS_MAP_NSS_MAX];
+};
+
+struct bwfm_sta_rateset_v7 {
+	uint16_t version;
+	uint16_t len;
+	uint32_t count;
+	/* rates in 500kbps units w/hi bit set if basic */
+	uint8_t rates[BWFM_MAXRATES_IN_SET];
+	uint8_t mcs[BWFM_MCSSET_LEN];
+	uint16_t vht_mcs[BWFM_VHT_CAP_MCS_MAP_NSS_MAX];
+	uint16_t he_mcs[BWFM_HE_CAP_MCS_MAP_NSS_MAX];
+};
+
+struct bwfm_sta_info {
+	uint16_t ver;
+	uint16_t len;
+	uint16_t cap;		/* sta's advertised capabilities */
+
+	uint32_t flags;
+#define BWFM_STA_BRCM		0x00000001 /* Running a Broadcom driver */
+#define BWFM_STA_WME		0x00000002 /* WMM association */
+#define BWFM_STA_NONERP		0x00000004 /* No ERP */
+#define BWFM_STA_AUTHE		0x00000008 /* Authenticated */
+#define BWFM_STA_ASSOC		0x00000010 /* Associated */
+#define BWFM_STA_AUTHO		0x00000020 /* Authorized */
+#define BWFM_STA_WDS		0x00000040 /* Wireless Distribution System */
+#define BWFM_STA_WDS_LINKUP	0x00000080 /* WDS traffic/probes flowing */
+#define BWFM_STA_PS		0x00000100 /* STA in power save mode, says AP */
+#define BWFM_STA_APSD_BE	0x00000200 /* APSD for AC_BE default enabled */
+#define BWFM_STA_APSD_BK	0x00000400 /* APSD for AC_BK default enabled */
+#define BWFM_STA_APSD_VI	0x00000800 /* APSD for AC_VI default enabled */
+#define BWFM_STA_APSD_VO	0x00001000 /* APSD for AC_VO default enabled */
+#define BWFM_STA_N_CAP		0x00002000 /* STA 802.11n capable */
+#define BWFM_STA_SCBSTATS	0x00004000 /* Per STA debug stats */
+#define BWFM_STA_AMPDU_CAP	0x00008000 /* STA AMPDU capable */
+#define BWFM_STA_AMSDU_CAP	0x00010000 /* STA AMSDU capable */
+#define BWFM_STA_MIMO_PS	0x00020000 /* mimo ps mode is enabled */
+#define BWFM_STA_MIMO_RTS	0x00040000 /* send rts in mimo ps mode */
+#define BWFM_STA_RIFS_CAP	0x00080000 /* rifs enabled */
+#define BWFM_STA_VHT_CAP	0x00100000 /* STA VHT(11ac) capable */
+#define BWFM_STA_WPS		0x00200000 /* WPS state */
+#define BWFM_STA_DWDS_CAP	0x01000000 /* DWDS CAP */
+#define BWFM_STA_DWDS		0x02000000 /* DWDS active */
+
+	uint32_t idle;		/* time since data pkt rx'd from sta */
+	uint8_t ea[ETHER_ADDR_LEN];
+	uint32_t count;			/* # rates in this set */
+	uint8_t rates[BWFM_MAXRATES_IN_SET];	/* rates in 500kbps units */
+						/* w/hi bit set if basic */
+	uint32_t in;		/* seconds elapsed since associated */
+	uint32_t listen_interval_inms; /* Min Listen interval in ms for STA */
+
+	/* Fields valid for ver >= 3 */
+	uint32_t tx_pkts;	/* # of packets transmitted */
+	uint32_t tx_failures;	/* # of packets failed */
+	uint32_t rx_ucast_pkts;	/* # of unicast packets received */
+	uint32_t rx_mcast_pkts;	/* # of multicast packets received */
+	uint32_t tx_rate;	/* Rate of last successful tx frame, in bps */
+	uint32_t rx_rate;	/* Rate of last successful rx frame, in bps */
+	uint32_t rx_decrypt_succeeds;	/* # of packet decrypted successfully */
+	uint32_t rx_decrypt_failures;	/* # of packet decrypted failed */
+
+	/* Fields valid for ver >= 4 */
+	uint32_t tx_tot_pkts;    /* # of tx pkts (ucast + mcast) */
+	uint32_t rx_tot_pkts;    /* # of data packets recvd (uni + mcast) */
+	uint32_t tx_mcast_pkts;  /* # of mcast pkts txed */
+	uint64_t tx_tot_bytes;   /* data bytes txed (ucast + mcast) */
+	uint64_t rx_tot_bytes;   /* data bytes recvd (ucast + mcast) */
+	uint64_t tx_ucast_bytes; /* data bytes txed (ucast) */
+	uint64_t tx_mcast_bytes; /* # data bytes txed (mcast) */
+	uint64_t rx_ucast_bytes; /* data bytes recvd (ucast) */
+	uint64_t rx_mcast_bytes; /* data bytes recvd (mcast) */
+	int8_t rssi[BWFM_ANT_MAX];   /* per antenna rssi */
+	int8_t nf[BWFM_ANT_MAX];     /* per antenna noise floor */
+	uint16_t aid;                    /* association ID */
+	uint16_t ht_capabilities;        /* advertised ht caps */
+	uint16_t vht_flags;              /* converted vht flags */
+	uint32_t tx_pkts_retry_cnt;      /* # of frames where a retry was
+					 * exhausted.
+					 */
+	uint32_t tx_pkts_retry_exhausted; /* # of user frames where a retry
+					 * was exhausted
+					 */
+	int8_t rx_lastpkt_rssi[BWFM_ANT_MAX]; /* Per antenna RSSI of last
+					    * received data frame.
+					    */
+	/* TX WLAN retry/failure statistics:
+	 * Separated for host requested frames and locally generated frames.
+	 * Include unicast frame only where the retries/failures can be counted.
+	 */
+	uint32_t tx_pkts_total;          /* # user frames sent successfully */
+	uint32_t tx_pkts_retries;        /* # user frames retries */
+	uint32_t tx_pkts_fw_total;       /* # FW generated sent successfully */
+	uint32_t tx_pkts_fw_retries;     /* # retries for FW generated frames */
+	uint32_t tx_pkts_fw_retry_exhausted;	/* # FW generated where a retry
+						* was exhausted
+						*/
+	uint32_t rx_pkts_retried;        /* # rx with retry bit set */
+	uint32_t tx_rate_fallback;       /* lowest fallback TX rate */
+
+	union {
+		struct {
+			struct bwfm_sta_rateset_v5 rateset_adv;
+		} v5;
+
+		struct {
+			uint32_t rx_dur_total; /* user RX duration (estimate) */
+			uint16_t chanspec;
+			uint16_t pad_1;
+			struct bwfm_sta_rateset_v7 rateset_adv;
+			uint16_t wpauth;	/* authentication type */
+			uint8_t algo;		/* crypto alogorithm */
+			uint8_t pad_2;
+			uint32_t tx_rspec;/* Rate of last successful tx frame */
+			uint32_t rx_rspec;/* Rate of last successful rx frame */
+			uint32_t wnm_cap;
+		} v7;
+	};
+};
+
 struct bwfm_ssid {
 	uint32_t len;
 	uint8_t ssid[BWFM_MAX_SSID_LEN];

Reply via email to