The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/rtwn/rtl8188e/r88e_rx.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
    5  * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
    6  * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org>
    7  *
    8  * Permission to use, copy, modify, and distribute this software for any
    9  * purpose with or without fee is hereby granted, provided that the above
   10  * copyright notice and this permission notice appear in all copies.
   11  *
   12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   19  */
   20 
   21 #include <sys/cdefs.h>
   22 __FBSDID("$FreeBSD$");
   23 
   24 #include "opt_wlan.h"
   25 
   26 #include <sys/param.h>
   27 #include <sys/lock.h>
   28 #include <sys/mutex.h>
   29 #include <sys/mbuf.h>
   30 #include <sys/kernel.h>
   31 #include <sys/socket.h>
   32 #include <sys/systm.h>
   33 #include <sys/malloc.h>
   34 #include <sys/queue.h>
   35 #include <sys/taskqueue.h>
   36 #include <sys/bus.h>
   37 #include <sys/endian.h>
   38 #include <sys/linker.h>
   39 
   40 #include <net/if.h>
   41 #include <net/ethernet.h>
   42 #include <net/if_media.h>
   43 
   44 #include <net80211/ieee80211_var.h>
   45 #include <net80211/ieee80211_radiotap.h>
   46 #include <net80211/ieee80211_ratectl.h>
   47 
   48 #include <dev/rtwn/if_rtwnreg.h>
   49 #include <dev/rtwn/if_rtwnvar.h>
   50 
   51 #include <dev/rtwn/if_rtwn_debug.h>
   52 #include <dev/rtwn/if_rtwn_ridx.h>
   53 
   54 #include <dev/rtwn/rtl8192c/r92c.h>
   55 #include <dev/rtwn/rtl8188e/r88e.h>
   56 #include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
   57 
   58 int
   59 r88e_classify_intr(struct rtwn_softc *sc, void *buf, int len)
   60 {
   61         struct r92c_rx_stat *stat = buf;
   62         int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT);
   63 
   64         switch (report_sel) {
   65         case R88E_RXDW3_RPT_RX:
   66                 return (RTWN_RX_DATA);
   67         case R88E_RXDW3_RPT_TX1:        /* per-packet Tx report */
   68         case R88E_RXDW3_RPT_TX2:        /* periodical Tx report */
   69                 return (RTWN_RX_TX_REPORT);
   70         case R88E_RXDW3_RPT_HIS:
   71                 return (RTWN_RX_OTHER);
   72         default:                        /* shut up the compiler */
   73                 return (RTWN_RX_DATA);
   74         }
   75 }
   76 
   77 void
   78 r88e_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
   79 {
   80 #if __FreeBSD_version >= 1200012
   81         struct ieee80211_ratectl_tx_status txs;
   82 #endif
   83         struct r88e_tx_rpt_ccx *rpt;
   84         struct ieee80211_node *ni;
   85         uint8_t macid;
   86         int ntries;
   87 
   88         /* Skip Rx descriptor. */
   89         buf += sizeof(struct r92c_rx_stat);
   90         len -= sizeof(struct r92c_rx_stat);
   91 
   92         rpt = (struct r88e_tx_rpt_ccx *)buf;
   93         if (len != sizeof(*rpt)) {
   94                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
   95                     "%s: wrong report size (%d, must be %zu)\n",
   96                     __func__, len, sizeof(*rpt));
   97                 return;
   98         }
   99 
  100         RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
  101             "%s: ccx report dump: 0: %02X, 1: %02X, 2: %02X, queue time: "
  102             "low %02X, high %02X, final ridx: %02X, 6: %02X, 7: %02X\n",
  103             __func__, rpt->rptb0, rpt->rptb1, rpt->rptb2, rpt->queue_time_low,
  104             rpt->queue_time_high, rpt->final_rate, rpt->rptb6, rpt->rptb7);
  105 
  106         macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
  107         if (macid > sc->macid_limit) {
  108                 device_printf(sc->sc_dev,
  109                     "macid %u is too big; increase MACID_MAX limit\n",
  110                     macid);
  111                 return;
  112         }
  113 
  114         ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
  115 
  116         ni = sc->node_list[macid];
  117         if (ni != NULL) {
  118                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: frame for macid %u was"
  119                     "%s sent (%d retries)\n", __func__, macid,
  120                     (rpt->rptb1 & R88E_RPTB1_PKT_OK) ? "" : " not",
  121                     ntries);
  122 
  123 #if __FreeBSD_version >= 1200012
  124                 txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY |
  125                             IEEE80211_RATECTL_STATUS_FINAL_RATE;
  126                 txs.long_retries = ntries;
  127                 if (rpt->final_rate > RTWN_RIDX_OFDM54) {       /* MCS */
  128                         txs.final_rate =
  129                             rpt->final_rate - RTWN_RIDX_HT_MCS_SHIFT;
  130                         txs.final_rate |= IEEE80211_RATE_MCS;
  131                 } else
  132                         txs.final_rate = ridx2rate[rpt->final_rate];
  133                 if (rpt->rptb1 & R88E_RPTB1_PKT_OK)
  134                         txs.status = IEEE80211_RATECTL_TX_SUCCESS;
  135                 else if (rpt->rptb2 & R88E_RPTB2_RETRY_OVER)
  136                         txs.status = IEEE80211_RATECTL_TX_FAIL_LONG;
  137                 else if (rpt->rptb2 & R88E_RPTB2_LIFE_EXPIRE)
  138                         txs.status = IEEE80211_RATECTL_TX_FAIL_EXPIRED;
  139                 else
  140                         txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
  141                 ieee80211_ratectl_tx_complete(ni, &txs);
  142 #else
  143                 struct ieee80211vap *vap = ni->ni_vap;
  144                 if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
  145                         ieee80211_ratectl_tx_complete(vap, ni,
  146                             IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
  147                 } else {
  148                         ieee80211_ratectl_tx_complete(vap, ni,
  149                             IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
  150                 }
  151 #endif
  152         } else {
  153                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: macid %u, ni is NULL\n",
  154                     __func__, macid);
  155         }
  156 }
  157 
  158 void
  159 r88e_handle_c2h_report(struct rtwn_softc *sc, uint8_t *buf, int len)
  160 {
  161 
  162         /* Skip Rx descriptor. */
  163         buf += sizeof(struct r92c_rx_stat);
  164         len -= sizeof(struct r92c_rx_stat);
  165 
  166         if (len != R88E_INTR_MSG_LEN) {
  167                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
  168                     "%s: wrong interrupt message size (%d, must be %d)\n",
  169                     __func__, len, R88E_INTR_MSG_LEN);
  170                 return;
  171         }
  172 
  173         /* XXX TODO */
  174 }
  175 
  176 int8_t
  177 r88e_get_rssi_cck(struct rtwn_softc *sc, void *physt)
  178 {
  179         struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
  180         int8_t lna_idx, vga_idx, rssi;
  181 
  182         lna_idx = (phy->agc_rpt & 0xe0) >> 5;
  183         vga_idx = (phy->agc_rpt & 0x1f);
  184         rssi = 6 - 2 * vga_idx;
  185 
  186         switch (lna_idx) {
  187         case 7:
  188                 if (vga_idx > 27)
  189                         rssi = -100 + 6;
  190                 else
  191                         rssi += -100 + 2 * 27;
  192                 break;
  193         case 6:
  194                 rssi += -48 + 2 * 2;
  195                 break;
  196         case 5:
  197                 rssi += -42 + 2 * 7;
  198                 break;
  199         case 4:
  200                 rssi += -36 + 2 * 7;
  201                 break;
  202         case 3:
  203                 rssi += -24 + 2 * 7;
  204                 break;
  205         case 2:
  206                 rssi += -6 + 2 * 5;
  207                 if (sc->sc_flags & RTWN_FLAG_CCK_HIPWR)
  208                         rssi -= 6;
  209                 break;
  210         case 1:
  211                 rssi += 8;
  212                 break;
  213         case 0:
  214                 rssi += 14;
  215                 break;
  216         }
  217 
  218         return (rssi);
  219 }
  220 
  221 int8_t
  222 r88e_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
  223 {
  224         struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
  225         int rssi;
  226 
  227         /* Get average RSSI. */
  228         rssi = ((phy->sig_qual >> 1) & 0x7f) - 110;
  229 
  230         return (rssi);
  231 }
  232 
  233 void
  234 r88e_get_rx_stats(struct rtwn_softc *sc, struct ieee80211_rx_stats *rxs,
  235     const void *desc, const void *physt_ptr)
  236 {
  237         const struct r88e_rx_phystat *physt = physt_ptr;
  238 
  239         r92c_get_rx_stats(sc, rxs, desc, physt_ptr);
  240 
  241         if (!sc->sc_ht40) {     /* XXX center channel */
  242                 rxs->r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ;
  243                 rxs->r_flags |= IEEE80211_R_BAND;
  244                 rxs->c_ieee = physt->chan;
  245                 rxs->c_freq = ieee80211_ieee2mhz(rxs->c_ieee,
  246                     IEEE80211_CHAN_2GHZ);
  247                 rxs->c_band = IEEE80211_CHAN_2GHZ;
  248         }
  249 }

Cache object: 8337d1dec9fa804410324b661e31de1f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.