Author: avos
Date: Sun Dec 13 21:00:21 2015
New Revision: 292167
URL: https://svnweb.freebsd.org/changeset/base/292167

Log:
  urtwn: add rate control support for RTL8188EU.
  
  Tested with:
  - RTL8188EU, STA and HOSTAP modes.
  - RTL8188CUS, STA mode.
  
  Reviewed by:  kevlo
  Approved by:  adrian (mentor)
  Differential Revision:        https://reviews.freebsd.org/D4402

Modified:
  head/sys/dev/usb/wlan/if_urtwn.c
  head/sys/dev/usb/wlan/if_urtwnreg.h
  head/sys/dev/usb/wlan/if_urtwnvar.h

Modified: head/sys/dev/usb/wlan/if_urtwn.c
==============================================================================
--- head/sys/dev/usb/wlan/if_urtwn.c    Sun Dec 13 20:53:51 2015        
(r292166)
+++ head/sys/dev/usb/wlan/if_urtwn.c    Sun Dec 13 21:00:21 2015        
(r292167)
@@ -183,8 +183,12 @@ static struct ieee80211vap *urtwn_vap_cr
 static void            urtwn_vap_delete(struct ieee80211vap *);
 static struct mbuf *   urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int,
                            int *);
-static struct mbuf *   urtwn_rxeof(struct usb_xfer *, struct urtwn_data *,
+static struct mbuf *   urtwn_report_intr(struct usb_xfer *, struct urtwn_data 
*,
                            int *, int8_t *);
+static struct mbuf *   urtwn_rxeof(struct urtwn_softc *, uint8_t *, int,
+                           int *, int8_t *);
+static void            urtwn_r88e_ratectl_tx_complete(struct urtwn_softc *,
+                           void *);
 static void            urtwn_txeof(struct urtwn_softc *, struct urtwn_data *,
                            int);
 static int             urtwn_alloc_list(struct urtwn_softc *,
@@ -295,6 +299,10 @@ static int         urtwn_wme_update(struct ieee
 static void            urtwn_set_promisc(struct urtwn_softc *);
 static void            urtwn_update_promisc(struct ieee80211com *);
 static void            urtwn_update_mcast(struct ieee80211com *);
+static struct ieee80211_node *urtwn_r88e_node_alloc(struct ieee80211vap *,
+                           const uint8_t mac[IEEE80211_ADDR_LEN]);
+static void            urtwn_r88e_newassoc(struct ieee80211_node *, int);
+static void            urtwn_r88e_node_free(struct ieee80211_node *);
 static void            urtwn_set_chan(struct urtwn_softc *,
                            struct ieee80211_channel *,
                            struct ieee80211_channel *);
@@ -419,6 +427,7 @@ urtwn_attach(device_t self)
 
        mtx_init(&sc->sc_mtx, device_get_nameunit(self),
            MTX_NETWORK_LOCK, MTX_DEF);
+       URTWN_NT_LOCK_INIT(sc);
        callout_init(&sc->sc_watchdog_ch, 0);
        mbufq_init(&sc->sc_snd, ifqmaxlen);
 
@@ -504,6 +513,12 @@ urtwn_attach(device_t self)
        ic->ic_wme.wme_update = urtwn_wme_update;
        ic->ic_update_promisc = urtwn_update_promisc;
        ic->ic_update_mcast = urtwn_update_mcast;
+       if (sc->chip & URTWN_CHIP_88E) {
+               ic->ic_node_alloc = urtwn_r88e_node_alloc;
+               ic->ic_newassoc = urtwn_r88e_newassoc;
+               sc->sc_node_free = ic->ic_node_free;
+               ic->ic_node_free = urtwn_r88e_node_free;
+       }
 
        ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
            sizeof(sc->sc_txtap), URTWN_TX_RADIOTAP_PRESENT,
@@ -560,6 +575,7 @@ urtwn_detach(device_t self)
        URTWN_UNLOCK(sc);
 
        ieee80211_ifdetach(ic);
+       URTWN_NT_LOCK_DESTROY(sc);
        mtx_destroy(&sc->sc_mtx);
 
        return (0);
@@ -638,6 +654,8 @@ urtwn_vap_create(struct ieee80211com *ic
                TASK_INIT(&uvp->tsf_task_adhoc, 0, urtwn_tsf_task_adhoc, vap);
        }
 
+       if (URTWN_CHIP_HAS_RATECTL(sc))
+               ieee80211_ratectl_init(vap);
        /* complete setup */
        ieee80211_vap_attach(vap, ieee80211_media_change,
            ieee80211_media_status, mac);
@@ -649,12 +667,15 @@ static void
 urtwn_vap_delete(struct ieee80211vap *vap)
 {
        struct ieee80211com *ic = vap->iv_ic;
+       struct urtwn_softc *sc = ic->ic_softc;
        struct urtwn_vap *uvp = URTWN_VAP(vap);
 
        if (uvp->bcn_mbuf != NULL)
                m_freem(uvp->bcn_mbuf);
        if (vap->iv_opmode == IEEE80211_M_IBSS)
                ieee80211_draintask(ic, &uvp->tsf_task_adhoc);
+       if (URTWN_CHIP_HAS_RATECTL(sc))
+               ieee80211_ratectl_deinit(vap);
        ieee80211_vap_detach(vap);
        free(uvp, M_80211_VAP);
 }
@@ -743,16 +764,14 @@ urtwn_rx_frame(struct urtwn_softc *sc, u
 }
 
 static struct mbuf *
-urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
+urtwn_report_intr(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
     int8_t *nf)
 {
        struct urtwn_softc *sc = data->sc;
        struct ieee80211com *ic = &sc->sc_ic;
        struct r92c_rx_stat *stat;
-       struct mbuf *m, *m0 = NULL, *prevm = NULL;
-       uint32_t rxdw0;
        uint8_t *buf;
-       int len, totlen, pktlen, infosz, npkts;
+       int len;
 
        usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
 
@@ -762,6 +781,36 @@ urtwn_rxeof(struct usb_xfer *xfer, struc
        }
 
        buf = data->buf;
+       stat = (struct r92c_rx_stat *)buf;
+
+       if (sc->chip & URTWN_CHIP_88E) {
+               int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT);
+
+               switch (report_sel) {
+               case R88E_RXDW3_RPT_RX:
+                       return (urtwn_rxeof(sc, buf, len, rssi, nf));
+               case R88E_RXDW3_RPT_TX1:
+                       urtwn_r88e_ratectl_tx_complete(sc, &stat[1]);
+                       break;
+               default:
+                       DPRINTFN(7, "case %d was not handled\n", report_sel);
+                       break;
+               }
+       } else
+               return (urtwn_rxeof(sc, buf, len, rssi, nf));
+
+       return (NULL);
+}
+
+static struct mbuf *
+urtwn_rxeof(struct urtwn_softc *sc, uint8_t *buf, int len, int *rssi,
+    int8_t *nf)
+{
+       struct r92c_rx_stat *stat;
+       struct mbuf *m, *m0 = NULL, *prevm = NULL;
+       uint32_t rxdw0;
+       int totlen, pktlen, infosz, npkts;
+
        /* Get the number of encapsulated frames. */
        stat = (struct r92c_rx_stat *)buf;
        npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT);
@@ -805,6 +854,35 @@ urtwn_rxeof(struct usb_xfer *xfer, struc
 }
 
 static void
+urtwn_r88e_ratectl_tx_complete(struct urtwn_softc *sc, void *arg)
+{
+       struct r88e_tx_rpt_ccx *rpt = arg;
+       struct ieee80211vap *vap;
+       struct ieee80211_node *ni;
+       uint8_t macid;
+       int ntries;
+
+       macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
+       ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
+
+       URTWN_NT_LOCK(sc);
+       ni = sc->node_list[macid];
+       if (ni != NULL) {
+               vap = ni->ni_vap;
+
+               if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
+                       ieee80211_ratectl_tx_complete(vap, ni,
+                           IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
+               } else {
+                       ieee80211_ratectl_tx_complete(vap, ni,
+                           IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
+               }
+       } else
+               DPRINTFN(8, "macid %d, ni is NULL\n", macid);
+       URTWN_NT_UNLOCK(sc);
+}
+
+static void
 urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
 {
        struct urtwn_softc *sc = usbd_xfer_softc(xfer);
@@ -824,7 +902,7 @@ urtwn_bulk_rx_callback(struct usb_xfer *
                if (data == NULL)
                        goto tr_setup;
                STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
-               m = urtwn_rxeof(xfer, data, &rssi, &nf);
+               m = urtwn_report_intr(xfer, data, &rssi, &nf);
                STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
                /* FALLTHROUGH */
        case USB_ST_SETUP:
@@ -2008,10 +2086,7 @@ urtwn_newstate(struct ieee80211vap *vap,
                urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);
 
                /* Intialize rate adaptation. */
-               if (sc->chip & URTWN_CHIP_88E)
-                       ni->ni_txrate =
-                           ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates-1];
-               else
+               if (!(sc->chip & URTWN_CHIP_88E))
                        urtwn_ra_init(sc);
                /* Turn link LED on. */
                urtwn_set_led(sc, URTWN_LED_LINK, 1);
@@ -2162,16 +2237,38 @@ urtwn_r88e_get_rssi(struct urtwn_softc *
        return (rssi);
 }
 
+static __inline uint8_t
+rate2ridx(uint8_t rate)
+{
+       switch (rate) {
+       case 12:        return 4;
+       case 18:        return 5;
+       case 24:        return 6;
+       case 36:        return 7;
+       case 48:        return 8;
+       case 72:        return 9;
+       case 96:        return 10;
+       case 108:       return 11;
+       case 2:         return 0;
+       case 4:         return 1;
+       case 11:        return 2;
+       case 22:        return 3;
+       default:        return 0;
+       }
+}
+
 static int
 urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
     struct mbuf *m, struct urtwn_data *data)
 {
-       struct ieee80211_frame *wh;
-       struct ieee80211_key *k = NULL;
+       const struct ieee80211_txparam *tp;
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211vap *vap = ni->ni_vap;
+       struct ieee80211_key *k = NULL;
+       struct ieee80211_channel *chan;
+       struct ieee80211_frame *wh;
        struct r92c_tx_desc *txd;
-       uint8_t macid, raid, ridx, subtype, type, tid, qsel;
+       uint8_t macid, raid, rate, ridx, subtype, type, tid, qsel;
        int hasqos, ismcast;
 
        URTWN_ASSERT_LOCKED(sc);
@@ -2192,6 +2289,38 @@ urtwn_tx_data(struct urtwn_softc *sc, st
        } else
                tid = 0;
 
+       chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
+               ni->ni_chan : ic->ic_curchan;
+       tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
+
+       /* Choose a TX rate index. */
+       if (type == IEEE80211_FC0_TYPE_MGT)
+               rate = tp->mgmtrate;
+       else if (ismcast)
+               rate = tp->mcastrate;
+       else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
+               rate = tp->ucastrate;
+       else if (m->m_flags & M_EAPOL)
+               rate = tp->mgmtrate;
+       else {
+               if (URTWN_CHIP_HAS_RATECTL(sc)) {
+                       /* XXX pass pktlen */
+                       (void) ieee80211_ratectl_rate(ni, NULL, 0);
+                       rate = ni->ni_txrate;
+               } else {
+                       if (ic->ic_curmode != IEEE80211_MODE_11B)
+                               rate = 108;
+                       else
+                               rate = 22;
+               }
+       }
+
+       ridx = rate2ridx(rate);
+       if (ic->ic_curmode != IEEE80211_MODE_11B)
+               raid = R92C_RAID_11BG;
+       else
+               raid = R92C_RAID_11B;
+
        if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m);
                if (k == NULL) {
@@ -2214,25 +2343,21 @@ urtwn_tx_data(struct urtwn_softc *sc, st
        if (ismcast)
                txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
 
-       raid = R92C_RAID_11B;   /* by default */
-       ridx = URTWN_RIDX_CCK1;
        if (!ismcast) {
-               macid = URTWN_MACID_BSS;
+               if (sc->chip & URTWN_CHIP_88E) {
+                       struct urtwn_node *un = URTWN_NODE(ni);
+                       macid = un->id;
+               } else
+                       macid = URTWN_MACID_BSS;
 
                if (type == IEEE80211_FC0_TYPE_DATA) {
                        qsel = tid % URTWN_MAX_TID;
 
-                       if (!(m->m_flags & M_EAPOL)) {
-                               if (ic->ic_curmode != IEEE80211_MODE_11B) {
-                                       raid = R92C_RAID_11BG;
-                                       ridx = URTWN_RIDX_OFDM54;
-                               } else
-                                       ridx = URTWN_RIDX_CCK11;
-                       }
-
-                       if (sc->chip & URTWN_CHIP_88E)
-                               txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
-                       else
+                       if (sc->chip & URTWN_CHIP_88E) {
+                               txd->txdw2 |= htole32(
+                                   R88E_TXDW2_AGGBK |
+                                   R88E_TXDW2_CCX_RPT);
+                       } else
                                txd->txdw1 |= htole32(R92C_TXDW1_AGGBK);
 
                        if (ic->ic_flags & IEEE80211_F_USEPROT) {
@@ -2272,8 +2397,8 @@ urtwn_tx_data(struct urtwn_softc *sc, st
 
        txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
        /* Force this rate if needed. */
-       if (ismcast || type != IEEE80211_FC0_TYPE_DATA ||
-           (m->m_flags & M_EAPOL))
+       if (URTWN_CHIP_HAS_RATECTL(sc) || ismcast ||
+           (m->m_flags & M_EAPOL) || type != IEEE80211_FC0_TYPE_DATA)
                txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
 
        if (!hasqos) {
@@ -3705,6 +3830,63 @@ urtwn_update_mcast(struct ieee80211com *
        /* XXX do nothing?  */
 }
 
+static struct ieee80211_node *
+urtwn_r88e_node_alloc(struct ieee80211vap *vap,
+    const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+       struct urtwn_node *un;
+
+       un = malloc(sizeof (struct urtwn_node), M_80211_NODE,
+           M_NOWAIT | M_ZERO);
+
+       if (un == NULL)
+               return NULL;
+
+       un->id = URTWN_MACID_UNDEFINED;
+
+       return &un->ni;
+}
+
+static void
+urtwn_r88e_newassoc(struct ieee80211_node *ni, int isnew)
+{
+       struct urtwn_softc *sc = ni->ni_ic->ic_softc;
+       struct urtwn_node *un = URTWN_NODE(ni);
+       uint8_t id;
+
+       if (!isnew)
+               return;
+
+       URTWN_NT_LOCK(sc);
+       for (id = 0; id <= URTWN_MACID_MAX(sc); id++) {
+               if (id != URTWN_MACID_BC && sc->node_list[id] == NULL) {
+                       un->id = id;
+                       sc->node_list[id] = ni;
+                       break;
+               }
+       }
+       URTWN_NT_UNLOCK(sc);
+
+       if (id > URTWN_MACID_MAX(sc)) {
+               device_printf(sc->sc_dev, "%s: node table is full\n",
+                   __func__);
+       }
+}
+
+static void
+urtwn_r88e_node_free(struct ieee80211_node *ni)
+{
+       struct urtwn_softc *sc = ni->ni_ic->ic_softc;
+       struct urtwn_node *un = URTWN_NODE(ni);
+
+       URTWN_NT_LOCK(sc);
+       if (un->id != URTWN_MACID_UNDEFINED)
+               sc->node_list[un->id] = NULL;
+       URTWN_NT_UNLOCK(sc);
+
+       sc->sc_node_free(ni);
+}
+
 static void
 urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
     struct ieee80211_channel *extc)
@@ -4022,6 +4204,12 @@ urtwn_init(struct urtwn_softc *sc)
        /* Enable hardware sequence numbering. */
        urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff);
 
+       /* Enable per-packet TX report. */
+       if (sc->chip & URTWN_CHIP_88E) {
+               urtwn_write_1(sc, R88E_TX_RPT_CTRL,
+                   urtwn_read_1(sc, R88E_TX_RPT_CTRL) | R88E_TX_RPT1_ENA);
+       }
+
        /* Perform LO and IQ calibrations. */
        urtwn_iq_calib(sc);
        /* Perform LC calibration. */

Modified: head/sys/dev/usb/wlan/if_urtwnreg.h
==============================================================================
--- head/sys/dev/usb/wlan/if_urtwnreg.h Sun Dec 13 20:53:51 2015        
(r292166)
+++ head/sys/dev/usb/wlan/if_urtwnreg.h Sun Dec 13 21:00:21 2015        
(r292167)
@@ -158,6 +158,9 @@
 #define R92C_INIRTS_RATE_SEL           0x480
 #define R92C_INIDATA_RATE_SEL(macid)   (0x484 + (macid))
 #define R92C_MAX_AGGR_NUM              0x4ca
+#define R88E_TX_RPT_CTRL               0x4ec
+#define R88E_TX_RPT_MACID_MAX          0x4ed
+#define R88E_TX_RPT_TIME               0x4f0
 /* EDCA Configuration. */
 #define R92C_EDCA_VO_PARAM             0x500
 #define R92C_EDCA_VI_PARAM             0x504
@@ -479,6 +482,10 @@
 #define R92C_RRSR_RSC_UPSUBCHNL                0x00400000
 #define R92C_RRSR_SHORT                        0x00800000
 
+/* Bits for R88E_TX_RPT_CTRL. */
+#define R88E_TX_RPT1_ENA               0x01
+#define R88E_TX_RPT2_ENA               0x02
+
 /* Bits for R92C_EDCA_XX_PARAM. */
 #define R92C_EDCA_PARAM_AIFS_M         0x000000ff
 #define R92C_EDCA_PARAM_AIFS_S         0
@@ -895,6 +902,11 @@ struct r92c_fw_cmd_macid_cfg {
        uint8_t         macid;
 #define URTWN_MACID_BSS                0
 #define URTWN_MACID_BC         4       /* Broadcast. */
+#define R92C_MACID_MAX         31
+#define R88E_MACID_MAX         63
+#define URTWN_MACID_MAX(sc)    (((sc)->chip & URTWN_CHIP_88E) ? \
+                                   R88E_MACID_MAX : R92C_MACID_MAX)
+#define URTWN_MACID_UNDEFINED  (uint8_t)-1
 #define URTWN_MACID_VALID      0x80
 } __packed;
 
@@ -972,6 +984,11 @@ struct r92c_rx_stat {
 #define R92C_RXDW3_RATE_S      0
 #define R92C_RXDW3_HT          0x00000040
 #define R92C_RXDW3_HTC         0x00000400
+#define R88E_RXDW3_RPT_M       0x0000c000
+#define R88E_RXDW3_RPT_S       14
+#define R88E_RXDW3_RPT_RX      0
+#define R88E_RXDW3_RPT_TX1     1
+#define R88E_RXDW3_RPT_TX2     2
 
        uint32_t        rxdw4;
        uint32_t        rxdw5;
@@ -1059,6 +1076,7 @@ struct r92c_tx_desc {
 
        uint32_t        txdw2;
 #define R88E_TXDW2_AGGBK       0x00010000
+#define R88E_TXDW2_CCX_RPT     0x00080000
 
        uint16_t        txdw3;
        uint16_t        txdseq;
@@ -1091,6 +1109,30 @@ struct r92c_tx_desc {
        uint16_t        pad;
 } __packed __attribute__((aligned(4)));
 
+struct r88e_tx_rpt_ccx {
+       uint8_t         rptb0;
+       uint8_t         rptb1;
+#define R88E_RPTB1_MACID_M     0x3f
+#define R88E_RPTB1_MACID_S     0
+#define R88E_RPTB1_PKT_OK      0x40
+#define R88E_RPTB1_BMC         0x80
+
+       uint8_t         rptb2;
+#define R88E_RPTB2_RETRY_CNT_M 0x3f
+#define R88E_RPTB2_RETRY_CNT_S 0
+#define R88E_RPTB2_LIFE_EXPIRE 0x40
+#define R88E_RPTB2_RETRY_OVER  0x80
+
+       uint8_t         rptb3;
+       uint8_t         rptb4;
+       uint8_t         rptb5;
+       uint8_t         rptb6;
+#define R88E_RPTB6_QSEL_M      0xf0
+#define R88E_RPTB6_QSEL_S      4
+
+       uint8_t         rptb7;
+} __packed;
+
 
 static const uint8_t ridx2rate[] =
        { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };

Modified: head/sys/dev/usb/wlan/if_urtwnvar.h
==============================================================================
--- head/sys/dev/usb/wlan/if_urtwnvar.h Sun Dec 13 20:53:51 2015        
(r292166)
+++ head/sys/dev/usb/wlan/if_urtwnvar.h Sun Dec 13 21:00:21 2015        
(r292167)
@@ -86,6 +86,12 @@ struct urtwn_fw_info {
        size_t                  size;
 };
 
+struct urtwn_node {
+       struct ieee80211_node   ni;     /* must be the first */
+       uint8_t                 id;
+};
+#define URTWN_NODE(ni) ((struct urtwn_node *)(ni))
+
 struct urtwn_vap {
        struct ieee80211vap     vap;
 
@@ -152,10 +158,16 @@ struct urtwn_softc {
 #define        URTWN_CHIP_UMC_A_CUT    0x08
 #define        URTWN_CHIP_88E          0x10
 
+#define URTWN_CHIP_HAS_RATECTL(_sc)    (!!((_sc)->chip & URTWN_CHIP_88E))
+
+       void                            (*sc_node_free)(struct ieee80211_node 
*);
        void                            (*sc_rf_write)(struct urtwn_softc *,
                                            int, uint8_t, uint32_t);
        int                             (*sc_power_on)(struct urtwn_softc *);
 
+       struct ieee80211_node           *node_list[R88E_MACID_MAX];
+       struct mtx                      nt_mtx;
+
        uint8_t                         board_type;
        uint8_t                         regulatory;
        uint8_t                         pa_setting;
@@ -213,3 +225,9 @@ struct urtwn_softc {
 #define        URTWN_LOCK(sc)                  mtx_lock(&(sc)->sc_mtx)
 #define        URTWN_UNLOCK(sc)                mtx_unlock(&(sc)->sc_mtx)
 #define        URTWN_ASSERT_LOCKED(sc)         mtx_assert(&(sc)->sc_mtx, 
MA_OWNED)
+
+#define URTWN_NT_LOCK_INIT(sc) \
+       mtx_init(&(sc)->nt_mtx, "node table lock", NULL, MTX_DEF)
+#define URTWN_NT_LOCK(sc)              mtx_lock(&(sc)->nt_mtx)
+#define URTWN_NT_UNLOCK(sc)            mtx_unlock(&(sc)->nt_mtx)
+#define URTWN_NT_LOCK_DESTROY(sc)      mtx_destroy(&(sc)->nt_mtx)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to