> 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;
> >     }
> >  
> > 
> > 
> 
> 

Reply via email to