From 6c29569229222107dbd33d774b06411ea5e41d5e Mon Sep 17 00:00:00 2001 From: hselasky Date: Tue, 15 Mar 2016 15:24:55 +0000 Subject: Improve detection of extended QSFP diagnostics. The standards in the QSFP diagnostics area are not clear when the additional measurements are present or not. Use a valid temperature reading as an indicator for the presence of voltage and TX/RX power measurements. MFC after: 1 week Sponsored by: Mellanox Technologies Tested by: Netflix Differential Revision: https://reviews.freebsd.org/D5391 Reviewed by: gallatin --- sbin/ifconfig/sfp.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'sbin/ifconfig') diff --git a/sbin/ifconfig/sfp.c b/sbin/ifconfig/sfp.c index 306140a..d92ee2c 100644 --- a/sbin/ifconfig/sfp.c +++ b/sbin/ifconfig/sfp.c @@ -625,14 +625,17 @@ get_sfp_voltage(struct i2c_info *ii, char *buf, size_t size) convert_sff_voltage(buf, size, xbuf); } -static void +static int get_qsfp_temp(struct i2c_info *ii, char *buf, size_t size) { uint8_t xbuf[2]; memset(xbuf, 0, sizeof(xbuf)); read_i2c(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf); + if ((xbuf[0] == 0xFF && xbuf[1] == 0xFF) || (xbuf[0] == 0 && xbuf[1] == 0)) + return (-1); convert_sff_temp(buf, size, xbuf); + return (0); } static void @@ -779,22 +782,9 @@ static void print_qsfp_status(struct i2c_info *ii, int verbose) { char buf[80], buf2[40], buf3[40]; - uint8_t diag_type; uint32_t bitrate; int i; - /* Read diagnostic monitoring type */ - read_i2c(ii, SFF_8436_BASE, SFF_8436_DIAG_TYPE, 1, (caddr_t)&diag_type); - if (ii->error != 0) - return; - - /* - * Read monitoring data it is supplied. - * XXX: It is not exactly clear from standard - * how one can specify lack of measurements (passive cables case). - */ - if (diag_type != 0) - ii->do_diag = 1; ii->qsfp = 1; /* Transceiver type */ @@ -817,9 +807,13 @@ print_qsfp_status(struct i2c_info *ii, int verbose) printf("\tnominal bitrate: %u Mbps\n", bitrate); } - /* Request current measurements if they are provided: */ - if (ii->do_diag != 0) { - get_qsfp_temp(ii, buf, sizeof(buf)); + /* + * The standards in this area are not clear when the + * additional measurements are present or not. Use a valid + * temperature reading as an indicator for the presence of + * voltage and TX/RX power measurements. + */ + if (get_qsfp_temp(ii, buf, sizeof(buf)) == 0) { get_qsfp_voltage(ii, buf2, sizeof(buf2)); printf("\tmodule temperature: %s voltage: %s\n", buf, buf2); for (i = 1; i <= 4; i++) { -- cgit v1.1 From 7c300189de77703235cdc36c616821af022cc3bd Mon Sep 17 00:00:00 2001 From: adrian Date: Wed, 16 Mar 2016 06:27:57 +0000 Subject: Display the VHT IE names. This doesn't decode the IEs just yet. Tested: * Archer c2 AP: TP-LINK_D579_5G 60:e3:27:e1:d5:78 44 54M 26:0 100 EP SSID RATES DSPARMS<44> COUNTRY TIM<050400010000> HTCAP HTINFO VHTCAP VHTOPMODE RSN WME BSSLOAD<0b05000001127a> VEN --- sbin/ifconfig/ifieee80211.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sbin/ifconfig') diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index 5ababf3..cb86a25 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -3087,6 +3087,9 @@ iename(int elemid) case IEEE80211_ELEMID_APCHANREP:return " APCHANREP"; case IEEE80211_ELEMID_TPC: return " TPC"; case IEEE80211_ELEMID_CCKM: return " CCKM"; + case IEEE80211_ELEMID_VHT_CAP: return " VHTCAP"; + case IEEE80211_ELEMID_VHT_OPMODE: return " VHTOPMODE"; + case IEEE80211_ELEMID_VHT_PWR_ENV: return " VHTPWRENV"; } return " ???"; } -- cgit v1.1 From 08bc03ce8e1452fea8b564e81c986ff34de76fe7 Mon Sep 17 00:00:00 2001 From: adrian Date: Fri, 18 Mar 2016 03:55:57 +0000 Subject: Decode VHTCAP, VHTINFO and BSSLOAD. BSSLOAD is based on work from Idwer Vollering. Obtained from: Idwer Vollering (bssload) --- sbin/ifconfig/ifieee80211.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'sbin/ifconfig') diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index cb86a25..a2622f1 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -2534,6 +2534,45 @@ printwmeinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) } static void +printvhtcap(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ + printf("%s", tag); + if (verbose) { + const struct ieee80211_ie_vhtcap *vhtcap = + (const struct ieee80211_ie_vhtcap *) ie; + uint32_t vhtcap_info = LE_READ_4(&vhtcap->vht_cap_info); + + printf("supp_mcs.rx_mcs_map)); + printf(" rx_highest %d", + LE_READ_2(&vhtcap->supp_mcs.rx_highest) & 0x1fff); + printf(" tx_mcs_map 0x%x", + LE_READ_2(&vhtcap->supp_mcs.tx_mcs_map)); + printf(" tx_highest %d", + LE_READ_2(&vhtcap->supp_mcs.tx_highest) & 0x1fff); + + printf(">"); + } +} + +static void +printvhtinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ + printf("%s", tag); + if (verbose) { + const struct ieee80211_ie_vht_operation *vhtinfo = + (const struct ieee80211_ie_vht_operation *) ie; + + printf("", + vhtinfo->chan_width, + vhtinfo->center_freq_seg1_idx, + vhtinfo->center_freq_seg2_idx, + LE_READ_2(&vhtinfo->basic_mcs_set)); + } +} + +static void printhtcap(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) { printf("%s", tag); @@ -2674,6 +2713,20 @@ do { \ #undef MATCHOUI } +static void +printbssload(const char *tag, const uint8_t *ie, size_t ielen, int maxlen) +{ + printf("%s", tag); + if (verbose) { + const struct ieee80211_bss_load_ie *bssload = + (const struct ieee80211_bss_load_ie *) ie; + printf("", + LE_READ_2(&bssload->sta_count), + bssload->chan_load, + bssload->aac); + } +} + static const char * wpa_cipher(const u_int8_t *sel) { @@ -3154,6 +3207,15 @@ printies(const u_int8_t *vp, int ielen, int maxcols) case IEEE80211_ELEMID_MESHCONF: printmeshconf(" MESHCONF", vp, 2+vp[1], maxcols); break; + case IEEE80211_ELEMID_VHT_CAP: + printvhtcap(" VHTCAP", vp, 2+vp[1], maxcols); + break; + case IEEE80211_ELEMID_VHT_OPMODE: + printvhtinfo(" VHTOPMODE", vp, 2+vp[1], maxcols); + break; + case IEEE80211_ELEMID_BSSLOAD: + printbssload(" BSSLOAD", vp, 2+vp[1], maxcols); + break; default: if (verbose) printie(iename(vp[0]), vp, 2+vp[1], maxcols); -- cgit v1.1 From bda76cd476a00a8677462ccf8a6a95f6d02cc410 Mon Sep 17 00:00:00 2001 From: adrian Date: Fri, 18 Mar 2016 04:09:27 +0000 Subject: Remove duplicate LE_READ_4() definition. Tested: * typed 'make', seemed to work. --- sbin/ifconfig/ifieee80211.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'sbin/ifconfig') diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index a2622f1..a0247a7 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -3071,14 +3071,6 @@ printcountry(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) printf(">"); } -/* unaligned little endian access */ -#define LE_READ_4(p) \ - ((u_int32_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8) | \ - (((const u_int8_t *)(p))[2] << 16) | \ - (((const u_int8_t *)(p))[3] << 24))) - static __inline int iswpaoui(const u_int8_t *frm) { -- cgit v1.1 From 8174750b975475469f3a5bf49cc8eb094d9f6820 Mon Sep 17 00:00:00 2001 From: adrian Date: Fri, 18 Mar 2016 04:22:07 +0000 Subject: Add parsing for AP channel report IE. Eg: TP-LINK_D579 60:e3:27:e1:d5:79 10 54M -72:-95 100 EP SSID RATES DSPARMS<10> XRATES<12,24,48,96> COUNTRY APCHANREP APCHANREP TIM<050400010000> ERP<0x4> HTCAP HTINFO ???<4a0e14000a002c01c800140005001900> RSN WME BSSLOAD VEN --- sbin/ifconfig/ifieee80211.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'sbin/ifconfig') diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index a0247a7..84daec9 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -2727,6 +2727,26 @@ printbssload(const char *tag, const uint8_t *ie, size_t ielen, int maxlen) } } +static void +printapchanrep(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) +{ + printf("%s", tag); + if (verbose) { + const struct ieee80211_ap_chan_report_ie *ap = + (const struct ieee80211_ap_chan_report_ie *) ie; + const char *sep = ""; + int i; + + printf("i_class); + + for (i = 3; i < ielen; i++) { + printf("%s%u", sep, ie[i]); + sep = ","; + } + printf("]>"); + } +} + static const char * wpa_cipher(const u_int8_t *sel) { @@ -3129,11 +3149,8 @@ iename(int elemid) case IEEE80211_ELEMID_MEASREP: return " MEASREP"; case IEEE80211_ELEMID_QUIET: return " QUIET"; case IEEE80211_ELEMID_IBSSDFS: return " IBSSDFS"; - case IEEE80211_ELEMID_APCHANREP:return " APCHANREP"; case IEEE80211_ELEMID_TPC: return " TPC"; case IEEE80211_ELEMID_CCKM: return " CCKM"; - case IEEE80211_ELEMID_VHT_CAP: return " VHTCAP"; - case IEEE80211_ELEMID_VHT_OPMODE: return " VHTOPMODE"; case IEEE80211_ELEMID_VHT_PWR_ENV: return " VHTPWRENV"; } return " ???"; @@ -3208,6 +3225,9 @@ printies(const u_int8_t *vp, int ielen, int maxcols) case IEEE80211_ELEMID_BSSLOAD: printbssload(" BSSLOAD", vp, 2+vp[1], maxcols); break; + case IEEE80211_ELEMID_APCHANREP: + printapchanrep(" APCHANREP", vp, 2+vp[1], maxcols); + break; default: if (verbose) printie(iename(vp[0]), vp, 2+vp[1], maxcols); -- cgit v1.1