> Date: Sat, 8 Oct 2016 13:06:53 +0200 (CEST) > From: Mark Kettenis <mark.kette...@xs4all.nl> > > > Date: Fri, 7 Oct 2016 18:59:52 +0200 > > From: Stefan Sperling <s...@stsp.name> > > > > On Fri, Oct 07, 2016 at 03:28:19PM +0200, Stefan Sperling wrote: > > > Currently tcpdump shows "0 Mbit/s" for any frame sent with 11n HT MCS. > > > To make progress easier, I'd like to see which MCS are used on the air, > > > by any device. > > > > > > The change below matches what FreeBSD did to pass an MCS index via > > > radiotap. > > > This simply writes the MCS index into a previously unused range of rate > > > values. > > > This format is already recognized by third party tools such as wireshark > > > so let's just do it the same way. > > > > > > The diff below updates the radiotap docs, makes iwn pass the MCS index, > > > shows it in tcpdump. I can now see MCS with iwn in monitor mode. > > > > > > ok? > > > > Same diff, plus iwn now captures MIMO frames in monitor mode. > > The addition might need to be tested on a 1TR1 and 2T3R setups. I can > test the latter, but I have no hardware to test the former.
FWIW, this seems to cause no regressions on: iwn0 at pci2 dev 0 function 0 "Intel WiFi Link 5300" rev 0x00: msi, MIMO 3T3R, MoW, address 00:21:6a:13:67:82 Cheers, Mark > > Index: sys/net80211/ieee80211_radiotap.h > > =================================================================== > > RCS file: /cvs/src/sys/net80211/ieee80211_radiotap.h,v > > retrieving revision 1.13 > > diff -u -p -r1.13 ieee80211_radiotap.h > > --- sys/net80211/ieee80211_radiotap.h 12 Jan 2016 09:28:09 -0000 > > 1.13 > > +++ sys/net80211/ieee80211_radiotap.h 7 Oct 2016 13:15:59 -0000 > > @@ -90,9 +90,10 @@ struct ieee80211_radiotap_header { > > * For frequency-hopping radios, the hop set (first byte) > > * and pattern (second byte). > > * > > - * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s > > + * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s or MCS > > index > > * > > - * Tx/Rx data rate > > + * Tx/Rx data rate in units of 500kb/s. If the high bit (0x80) is set > > + * the remaining bits contain an MCS index instead of a date rate. > > * > > * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from > > * one milliwatt (dBm) > > Index: sys/dev/pci/if_iwn.c > > =================================================================== > > RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v > > retrieving revision 1.172 > > diff -u -p -r1.172 if_iwn.c > > --- sys/dev/pci/if_iwn.c 5 Sep 2016 08:18:18 -0000 1.172 > > +++ sys/dev/pci/if_iwn.c 7 Oct 2016 16:33:39 -0000 > > @@ -2131,23 +2131,27 @@ iwn_rx_done(struct iwn_softc *sc, struct > > tap->wr_dbm_antsignal = (int8_t)rssi; > > tap->wr_dbm_antnoise = (int8_t)sc->noise; > > tap->wr_tsft = stat->tstamp; > > - switch (stat->rate) { > > - /* CCK rates. */ > > - case 10: tap->wr_rate = 2; break; > > - case 20: tap->wr_rate = 4; break; > > - case 55: tap->wr_rate = 11; break; > > - case 110: tap->wr_rate = 22; break; > > - /* OFDM rates. */ > > - case 0xd: tap->wr_rate = 12; break; > > - case 0xf: tap->wr_rate = 18; break; > > - case 0x5: tap->wr_rate = 24; break; > > - case 0x7: tap->wr_rate = 36; break; > > - case 0x9: tap->wr_rate = 48; break; > > - case 0xb: tap->wr_rate = 72; break; > > - case 0x1: tap->wr_rate = 96; break; > > - case 0x3: tap->wr_rate = 108; break; > > - /* Unknown rate: should not happen. */ > > - default: tap->wr_rate = 0; > > + if (stat->rflags & IWN_RFLAG_MCS) { > > + tap->wr_rate = (0x80 | stat->rate); /* HT MCS index */ > > + } else { > > + switch (stat->rate) { > > + /* CCK rates. */ > > + case 10: tap->wr_rate = 2; break; > > + case 20: tap->wr_rate = 4; break; > > + case 55: tap->wr_rate = 11; break; > > + case 110: tap->wr_rate = 22; break; > > + /* OFDM rates. */ > > + case 0xd: tap->wr_rate = 12; break; > > + case 0xf: tap->wr_rate = 18; break; > > + case 0x5: tap->wr_rate = 24; break; > > + case 0x7: tap->wr_rate = 36; break; > > + case 0x9: tap->wr_rate = 48; break; > > + case 0xb: tap->wr_rate = 72; break; > > + case 0x1: tap->wr_rate = 96; break; > > + case 0x3: tap->wr_rate = 108; break; > > + /* Unknown rate: should not happen. */ > > + default: tap->wr_rate = 0; > > + } > > } > > > > mb.m_data = (caddr_t)tap; > > @@ -2876,8 +2880,7 @@ iwn_tx(struct iwn_softc *sc, struct mbuf > > if ((ni->ni_flags & IEEE80211_NODE_HT) && > > !IEEE80211_IS_MULTICAST(wh->i_addr1) && > > type == IEEE80211_FC0_TYPE_DATA) { > > - /* XXX need a way to pass current MCS in 11n mode */ > > - tap->wt_rate = 0; > > + tap->wt_rate = (0x80 | ni->ni_txmcs); > > } else > > tap->wt_rate = rinfo->rate; > > tap->wt_hwqueue = ac; > > @@ -4498,13 +4501,18 @@ iwn_config(struct iwn_softc *sc) > > sc->rxon.ht_triple_mask = 0xff; > > rxchain = > > IWN_RXCHAIN_VALID(sc->rxchainmask) | > > - IWN_RXCHAIN_MIMO_COUNT(2) | > > - IWN_RXCHAIN_IDLE_COUNT(2); > > + IWN_RXCHAIN_MIMO_COUNT(sc->nrxchains) | > > + IWN_RXCHAIN_IDLE_COUNT(sc->nrxchains); > > + if (ic->ic_opmode == IEEE80211_M_MONITOR) { > > + rxchain |= IWN_RXCHAIN_FORCE_SEL(sc->rxchainmask); > > + rxchain |= IWN_RXCHAIN_FORCE_MIMO_SEL(sc->rxchainmask); > > + rxchain |= (IWN_RXCHAIN_DRIVER_FORCE | IWN_RXCHAIN_MIMO_FORCE); > > + } > > sc->rxon.rxchain = htole16(rxchain); > > DPRINTF(("setting configuration\n")); > > - DPRINTF(("%s: rxon chan %d flags %x cck %x ofdm %x\n", __func__, > > - sc->rxon.chan, le32toh(sc->rxon.flags), sc->rxon.cck_mask, > > - sc->rxon.ofdm_mask)); > > + DPRINTF(("%s: rxon chan %d flags %x cck %x ofdm %x rxchain %x\n", > > + __func__, sc->rxon.chan, le32toh(sc->rxon.flags), sc->rxon.cck_mask, > > + sc->rxon.ofdm_mask, sc->rxon.rxchain)); > > error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 0); > > if (error != 0) { > > printf("%s: RXON command failed\n", sc->sc_dev.dv_xname); > > Index: usr.sbin/tcpdump/print-802_11.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v > > retrieving revision 1.33 > > diff -u -p -r1.33 print-802_11.c > > --- usr.sbin/tcpdump/print-802_11.c 2 Sep 2016 17:11:46 -0000 1.33 > > +++ usr.sbin/tcpdump/print-802_11.c 7 Oct 2016 12:44:25 -0000 > > @@ -1075,8 +1075,13 @@ ieee802_11_radio_if_print(u_char *user, > > > > if (RADIOTAP(RATE)) { > > TCHECK2(*t, 1); > > - if (vflag) > > - printf(", %uMbit/s", (*(u_int8_t*)t) / 2); > > + if (vflag) { > > + uint8_t rate = *(u_int8_t*)t; > > + if (rate & 0x80) > > + printf(", MCS %u", rate & 0x7f); > > + else > > + printf(", %uMbit/s", rate / 2); > > + } > > t += 1; > > } > > > > > > > >