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/contrib/dev/rtw88/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 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /* Copyright(c) 2018-2019  Realtek Corporation
    3  */
    4 
    5 #include "main.h"
    6 #include "rx.h"
    7 #include "ps.h"
    8 #include "debug.h"
    9 #include "fw.h"
   10 
   11 void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
   12                   struct sk_buff *skb)
   13 {
   14         struct ieee80211_hdr *hdr;
   15         struct rtw_vif *rtwvif;
   16 
   17         hdr = (struct ieee80211_hdr *)skb->data;
   18 
   19         if (!ieee80211_is_data(hdr->frame_control))
   20                 return;
   21 
   22         if (!is_broadcast_ether_addr(hdr->addr1) &&
   23             !is_multicast_ether_addr(hdr->addr1)) {
   24                 rtwdev->stats.rx_unicast += skb->len;
   25                 rtwdev->stats.rx_cnt++;
   26                 if (vif) {
   27                         rtwvif = (struct rtw_vif *)vif->drv_priv;
   28                         rtwvif->stats.rx_unicast += skb->len;
   29                         rtwvif->stats.rx_cnt++;
   30                 }
   31         }
   32 }
   33 EXPORT_SYMBOL(rtw_rx_stats);
   34 
   35 struct rtw_rx_addr_match_data {
   36         struct rtw_dev *rtwdev;
   37         struct ieee80211_hdr *hdr;
   38         struct rtw_rx_pkt_stat *pkt_stat;
   39         u8 *bssid;
   40 };
   41 
   42 static void rtw_rx_phy_stat(struct rtw_dev *rtwdev,
   43                             struct rtw_rx_pkt_stat *pkt_stat,
   44                             struct ieee80211_hdr *hdr)
   45 {
   46         struct rtw_dm_info *dm_info = &rtwdev->dm_info;
   47         struct rtw_pkt_count *cur_pkt_cnt = &dm_info->cur_pkt_count;
   48         u8 rate_ss, rate_ss_evm, evm_id;
   49         u8 i, idx;
   50 
   51         dm_info->curr_rx_rate = pkt_stat->rate;
   52 
   53         if (ieee80211_is_beacon(hdr->frame_control))
   54                 cur_pkt_cnt->num_bcn_pkt++;
   55 
   56         switch (pkt_stat->rate) {
   57         case DESC_RATE1M...DESC_RATE11M:
   58                 goto pkt_num;
   59         case DESC_RATE6M...DESC_RATE54M:
   60                 rate_ss = 0;
   61                 rate_ss_evm = 1;
   62                 evm_id = RTW_EVM_OFDM;
   63                 break;
   64         case DESC_RATEMCS0...DESC_RATEMCS7:
   65         case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT1SS_MCS9:
   66                 rate_ss = 1;
   67                 rate_ss_evm = 1;
   68                 evm_id = RTW_EVM_1SS;
   69                 break;
   70         case DESC_RATEMCS8...DESC_RATEMCS15:
   71         case DESC_RATEVHT2SS_MCS0...DESC_RATEVHT2SS_MCS9:
   72                 rate_ss = 2;
   73                 rate_ss_evm = 2;
   74                 evm_id = RTW_EVM_2SS_A;
   75                 break;
   76         default:
   77                 rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate);
   78                 return;
   79         }
   80 
   81         for (i = 0; i < rate_ss_evm; i++) {
   82                 idx = evm_id + i;
   83                 ewma_evm_add(&dm_info->ewma_evm[idx],
   84                              dm_info->rx_evm_dbm[i]);
   85         }
   86 
   87         for (i = 0; i < rtwdev->hal.rf_path_num; i++) {
   88                 idx = RTW_SNR_OFDM_A + 4 * rate_ss + i;
   89                 ewma_snr_add(&dm_info->ewma_snr[idx],
   90                              dm_info->rx_snr[i]);
   91         }
   92 pkt_num:
   93         cur_pkt_cnt->num_qry_pkt[pkt_stat->rate]++;
   94 }
   95 
   96 static void rtw_rx_addr_match_iter(void *data, u8 *mac,
   97                                    struct ieee80211_vif *vif)
   98 {
   99         struct rtw_rx_addr_match_data *iter_data = data;
  100         struct ieee80211_sta *sta;
  101         struct ieee80211_hdr *hdr = iter_data->hdr;
  102         struct rtw_dev *rtwdev = iter_data->rtwdev;
  103         struct rtw_sta_info *si;
  104         struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat;
  105         u8 *bssid = iter_data->bssid;
  106 
  107         if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
  108                 return;
  109 
  110         if (!(ether_addr_equal(vif->addr, hdr->addr1) ||
  111               ieee80211_is_beacon(hdr->frame_control)))
  112                 return;
  113 
  114         rtw_rx_phy_stat(rtwdev, pkt_stat, hdr);
  115         sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2,
  116                                            vif->addr);
  117         if (!sta)
  118                 return;
  119 
  120         si = (struct rtw_sta_info *)sta->drv_priv;
  121         ewma_rssi_add(&si->avg_rssi, pkt_stat->rssi);
  122 }
  123 
  124 static void rtw_rx_addr_match(struct rtw_dev *rtwdev,
  125                               struct rtw_rx_pkt_stat *pkt_stat,
  126                               struct ieee80211_hdr *hdr)
  127 {
  128         struct rtw_rx_addr_match_data data = {};
  129 
  130         if (pkt_stat->crc_err || pkt_stat->icv_err || !pkt_stat->phy_status ||
  131             ieee80211_is_ctl(hdr->frame_control))
  132                 return;
  133 
  134         data.rtwdev = rtwdev;
  135         data.hdr = hdr;
  136         data.pkt_stat = pkt_stat;
  137         data.bssid = get_hdr_bssid(hdr);
  138 
  139         rtw_iterate_vifs_atomic(rtwdev, rtw_rx_addr_match_iter, &data);
  140 }
  141 
  142 static void rtw_set_rx_freq_by_pktstat(struct rtw_rx_pkt_stat *pkt_stat,
  143                                        struct ieee80211_rx_status *rx_status)
  144 {
  145         rx_status->freq = pkt_stat->freq;
  146         rx_status->band = pkt_stat->band;
  147 }
  148 
  149 void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
  150                            struct rtw_rx_pkt_stat *pkt_stat,
  151                            struct ieee80211_hdr *hdr,
  152                            struct ieee80211_rx_status *rx_status,
  153                            u8 *phy_status)
  154 {
  155         struct ieee80211_hw *hw = rtwdev->hw;
  156         u8 path;
  157 
  158         memset(rx_status, 0, sizeof(*rx_status));
  159         rx_status->freq = hw->conf.chandef.chan->center_freq;
  160         rx_status->band = hw->conf.chandef.chan->band;
  161         if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) &&
  162             test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
  163                 rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status);
  164         if (pkt_stat->crc_err)
  165                 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
  166         if (pkt_stat->decrypted)
  167                 rx_status->flag |= RX_FLAG_DECRYPTED;
  168 
  169         if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0)
  170                 rx_status->encoding = RX_ENC_VHT;
  171         else if (pkt_stat->rate >= DESC_RATEMCS0)
  172                 rx_status->encoding = RX_ENC_HT;
  173 
  174         if (rx_status->band == NL80211_BAND_5GHZ &&
  175             pkt_stat->rate >= DESC_RATE6M &&
  176             pkt_stat->rate <= DESC_RATE54M) {
  177                 rx_status->rate_idx = pkt_stat->rate - DESC_RATE6M;
  178         } else if (rx_status->band == NL80211_BAND_2GHZ &&
  179                    pkt_stat->rate >= DESC_RATE1M &&
  180                    pkt_stat->rate <= DESC_RATE54M) {
  181                 rx_status->rate_idx = pkt_stat->rate - DESC_RATE1M;
  182         } else if (pkt_stat->rate >= DESC_RATEMCS0) {
  183                 rtw_desc_to_mcsrate(pkt_stat->rate, &rx_status->rate_idx,
  184                                     &rx_status->nss);
  185         }
  186 
  187         rx_status->flag |= RX_FLAG_MACTIME_START;
  188         rx_status->mactime = pkt_stat->tsf_low;
  189 
  190         if (pkt_stat->bw == RTW_CHANNEL_WIDTH_80)
  191                 rx_status->bw = RATE_INFO_BW_80;
  192         else if (pkt_stat->bw == RTW_CHANNEL_WIDTH_40)
  193                 rx_status->bw = RATE_INFO_BW_40;
  194         else
  195                 rx_status->bw = RATE_INFO_BW_20;
  196 
  197         rx_status->signal = pkt_stat->signal_power;
  198         for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
  199                 rx_status->chains |= BIT(path);
  200                 rx_status->chain_signal[path] = pkt_stat->rx_power[path];
  201         }
  202 
  203         rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
  204 }
  205 EXPORT_SYMBOL(rtw_rx_fill_rx_status);

Cache object: d6bb9869b772867325e871a48ca5b481


[ 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.