root/drivers/net/wireless/realtek/rtw88/tx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtw_tx_stats
  2. rtw_tx_fill_tx_desc
  3. get_tx_ampdu_factor
  4. get_tx_ampdu_density
  5. get_highest_ht_tx_rate
  6. get_highest_vht_tx_rate
  7. rtw_tx_report_enable
  8. rtw_tx_report_purge_timer
  9. rtw_tx_report_enqueue
  10. rtw_tx_report_tx_status
  11. rtw_tx_report_handle
  12. rtw_tx_mgmt_pkt_info_update
  13. rtw_tx_data_pkt_info_update
  14. rtw_tx_pkt_info_update
  15. rtw_rsvd_page_pkt_info_update

   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 "tx.h"
   7 #include "fw.h"
   8 #include "ps.h"
   9 
  10 static
  11 void rtw_tx_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.tx_unicast += skb->len;
  25                 rtwdev->stats.tx_cnt++;
  26                 if (vif) {
  27                         rtwvif = (struct rtw_vif *)vif->drv_priv;
  28                         rtwvif->stats.tx_unicast += skb->len;
  29                         rtwvif->stats.tx_cnt++;
  30                         if (rtwvif->stats.tx_cnt > RTW_LPS_THRESHOLD)
  31                                 rtw_leave_lps_irqsafe(rtwdev, rtwvif);
  32                 }
  33         }
  34 }
  35 
  36 void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
  37 {
  38         __le32 *txdesc = (__le32 *)skb->data;
  39 
  40         SET_TX_DESC_TXPKTSIZE(txdesc,  pkt_info->tx_pkt_size);
  41         SET_TX_DESC_OFFSET(txdesc, pkt_info->offset);
  42         SET_TX_DESC_PKT_OFFSET(txdesc, pkt_info->pkt_offset);
  43         SET_TX_DESC_QSEL(txdesc, pkt_info->qsel);
  44         SET_TX_DESC_BMC(txdesc, pkt_info->bmc);
  45         SET_TX_DESC_RATE_ID(txdesc, pkt_info->rate_id);
  46         SET_TX_DESC_DATARATE(txdesc, pkt_info->rate);
  47         SET_TX_DESC_DISDATAFB(txdesc, pkt_info->dis_rate_fallback);
  48         SET_TX_DESC_USE_RATE(txdesc, pkt_info->use_rate);
  49         SET_TX_DESC_SEC_TYPE(txdesc, pkt_info->sec_type);
  50         SET_TX_DESC_DATA_BW(txdesc, pkt_info->bw);
  51         SET_TX_DESC_SW_SEQ(txdesc, pkt_info->seq);
  52         SET_TX_DESC_MAX_AGG_NUM(txdesc, pkt_info->ampdu_factor);
  53         SET_TX_DESC_AMPDU_DENSITY(txdesc, pkt_info->ampdu_density);
  54         SET_TX_DESC_DATA_STBC(txdesc, pkt_info->stbc);
  55         SET_TX_DESC_DATA_LDPC(txdesc, pkt_info->ldpc);
  56         SET_TX_DESC_AGG_EN(txdesc, pkt_info->ampdu_en);
  57         SET_TX_DESC_LS(txdesc, pkt_info->ls);
  58         SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi);
  59         SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report);
  60         SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn);
  61 }
  62 EXPORT_SYMBOL(rtw_tx_fill_tx_desc);
  63 
  64 static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta)
  65 {
  66         u8 exp = sta->ht_cap.ampdu_factor;
  67 
  68         /* the least ampdu factor is 8K, and the value in the tx desc is the
  69          * max aggregation num, which represents val * 2 packets can be
  70          * aggregated in an AMPDU, so here we should use 8/2=4 as the base
  71          */
  72         return (BIT(2) << exp) - 1;
  73 }
  74 
  75 static u8 get_tx_ampdu_density(struct ieee80211_sta *sta)
  76 {
  77         return sta->ht_cap.ampdu_density;
  78 }
  79 
  80 static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev,
  81                                  struct ieee80211_sta *sta)
  82 {
  83         u8 rate;
  84 
  85         if (rtwdev->hal.rf_type == RF_2T2R && sta->ht_cap.mcs.rx_mask[1] != 0)
  86                 rate = DESC_RATEMCS15;
  87         else
  88                 rate = DESC_RATEMCS7;
  89 
  90         return rate;
  91 }
  92 
  93 static u8 get_highest_vht_tx_rate(struct rtw_dev *rtwdev,
  94                                   struct ieee80211_sta *sta)
  95 {
  96         struct rtw_efuse *efuse = &rtwdev->efuse;
  97         u8 rate;
  98         u16 tx_mcs_map;
  99 
 100         tx_mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map);
 101         if (efuse->hw_cap.nss == 1) {
 102                 switch (tx_mcs_map & 0x3) {
 103                 case IEEE80211_VHT_MCS_SUPPORT_0_7:
 104                         rate = DESC_RATEVHT1SS_MCS7;
 105                         break;
 106                 case IEEE80211_VHT_MCS_SUPPORT_0_8:
 107                         rate = DESC_RATEVHT1SS_MCS8;
 108                         break;
 109                 default:
 110                 case IEEE80211_VHT_MCS_SUPPORT_0_9:
 111                         rate = DESC_RATEVHT1SS_MCS9;
 112                         break;
 113                 }
 114         } else if (efuse->hw_cap.nss >= 2) {
 115                 switch ((tx_mcs_map & 0xc) >> 2) {
 116                 case IEEE80211_VHT_MCS_SUPPORT_0_7:
 117                         rate = DESC_RATEVHT2SS_MCS7;
 118                         break;
 119                 case IEEE80211_VHT_MCS_SUPPORT_0_8:
 120                         rate = DESC_RATEVHT2SS_MCS8;
 121                         break;
 122                 default:
 123                 case IEEE80211_VHT_MCS_SUPPORT_0_9:
 124                         rate = DESC_RATEVHT2SS_MCS9;
 125                         break;
 126                 }
 127         } else {
 128                 rate = DESC_RATEVHT1SS_MCS9;
 129         }
 130 
 131         return rate;
 132 }
 133 
 134 static void rtw_tx_report_enable(struct rtw_dev *rtwdev,
 135                                  struct rtw_tx_pkt_info *pkt_info)
 136 {
 137         struct rtw_tx_report *tx_report = &rtwdev->tx_report;
 138 
 139         /* [11:8], reserved, fills with zero
 140          * [7:2],  tx report sequence number
 141          * [1:0],  firmware use, fills with zero
 142          */
 143         pkt_info->sn = (atomic_inc_return(&tx_report->sn) << 2) & 0xfc;
 144         pkt_info->report = true;
 145 }
 146 
 147 void rtw_tx_report_purge_timer(struct timer_list *t)
 148 {
 149         struct rtw_dev *rtwdev = from_timer(rtwdev, t, tx_report.purge_timer);
 150         struct rtw_tx_report *tx_report = &rtwdev->tx_report;
 151         unsigned long flags;
 152 
 153         if (skb_queue_len(&tx_report->queue) == 0)
 154                 return;
 155 
 156         WARN(1, "purge skb(s) not reported by firmware\n");
 157 
 158         spin_lock_irqsave(&tx_report->q_lock, flags);
 159         skb_queue_purge(&tx_report->queue);
 160         spin_unlock_irqrestore(&tx_report->q_lock, flags);
 161 }
 162 
 163 void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
 164 {
 165         struct rtw_tx_report *tx_report = &rtwdev->tx_report;
 166         unsigned long flags;
 167         u8 *drv_data;
 168 
 169         /* pass sn to tx report handler through driver data */
 170         drv_data = (u8 *)IEEE80211_SKB_CB(skb)->status.status_driver_data;
 171         *drv_data = sn;
 172 
 173         spin_lock_irqsave(&tx_report->q_lock, flags);
 174         __skb_queue_tail(&tx_report->queue, skb);
 175         spin_unlock_irqrestore(&tx_report->q_lock, flags);
 176 
 177         mod_timer(&tx_report->purge_timer, jiffies + RTW_TX_PROBE_TIMEOUT);
 178 }
 179 EXPORT_SYMBOL(rtw_tx_report_enqueue);
 180 
 181 static void rtw_tx_report_tx_status(struct rtw_dev *rtwdev,
 182                                     struct sk_buff *skb, bool acked)
 183 {
 184         struct ieee80211_tx_info *info;
 185 
 186         info = IEEE80211_SKB_CB(skb);
 187         ieee80211_tx_info_clear_status(info);
 188         if (acked)
 189                 info->flags |= IEEE80211_TX_STAT_ACK;
 190         else
 191                 info->flags &= ~IEEE80211_TX_STAT_ACK;
 192 
 193         ieee80211_tx_status_irqsafe(rtwdev->hw, skb);
 194 }
 195 
 196 void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
 197 {
 198         struct rtw_tx_report *tx_report = &rtwdev->tx_report;
 199         struct rtw_c2h_cmd *c2h;
 200         struct sk_buff *cur, *tmp;
 201         unsigned long flags;
 202         u8 sn, st;
 203         u8 *n;
 204 
 205         c2h = get_c2h_from_skb(skb);
 206 
 207         sn = GET_CCX_REPORT_SEQNUM(c2h->payload);
 208         st = GET_CCX_REPORT_STATUS(c2h->payload);
 209 
 210         spin_lock_irqsave(&tx_report->q_lock, flags);
 211         skb_queue_walk_safe(&tx_report->queue, cur, tmp) {
 212                 n = (u8 *)IEEE80211_SKB_CB(cur)->status.status_driver_data;
 213                 if (*n == sn) {
 214                         __skb_unlink(cur, &tx_report->queue);
 215                         rtw_tx_report_tx_status(rtwdev, cur, st == 0);
 216                         break;
 217                 }
 218         }
 219         spin_unlock_irqrestore(&tx_report->q_lock, flags);
 220 }
 221 
 222 static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev,
 223                                         struct rtw_tx_pkt_info *pkt_info,
 224                                         struct ieee80211_tx_control *control,
 225                                         struct sk_buff *skb)
 226 {
 227         pkt_info->use_rate = true;
 228         pkt_info->rate_id = 6;
 229         pkt_info->dis_rate_fallback = true;
 230 }
 231 
 232 static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev,
 233                                         struct rtw_tx_pkt_info *pkt_info,
 234                                         struct ieee80211_tx_control *control,
 235                                         struct sk_buff *skb)
 236 {
 237         struct ieee80211_sta *sta = control->sta;
 238         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 239         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 240         struct rtw_sta_info *si;
 241         u16 seq;
 242         u8 ampdu_factor = 0;
 243         u8 ampdu_density = 0;
 244         bool ampdu_en = false;
 245         u8 rate = DESC_RATE6M;
 246         u8 rate_id = 6;
 247         u8 bw = RTW_CHANNEL_WIDTH_20;
 248         bool stbc = false;
 249         bool ldpc = false;
 250 
 251         seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 252 
 253         /* for broadcast/multicast, use default values */
 254         if (!sta)
 255                 goto out;
 256 
 257         if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 258                 ampdu_en = true;
 259                 ampdu_factor = get_tx_ampdu_factor(sta);
 260                 ampdu_density = get_tx_ampdu_density(sta);
 261         }
 262 
 263         if (sta->vht_cap.vht_supported)
 264                 rate = get_highest_vht_tx_rate(rtwdev, sta);
 265         else if (sta->ht_cap.ht_supported)
 266                 rate = get_highest_ht_tx_rate(rtwdev, sta);
 267         else if (sta->supp_rates[0] <= 0xf)
 268                 rate = DESC_RATE11M;
 269         else
 270                 rate = DESC_RATE54M;
 271 
 272         si = (struct rtw_sta_info *)sta->drv_priv;
 273 
 274         bw = si->bw_mode;
 275         rate_id = si->rate_id;
 276         stbc = si->stbc_en;
 277         ldpc = si->ldpc_en;
 278 
 279 out:
 280         pkt_info->seq = seq;
 281         pkt_info->ampdu_factor = ampdu_factor;
 282         pkt_info->ampdu_density = ampdu_density;
 283         pkt_info->ampdu_en = ampdu_en;
 284         pkt_info->rate = rate;
 285         pkt_info->rate_id = rate_id;
 286         pkt_info->bw = bw;
 287         pkt_info->stbc = stbc;
 288         pkt_info->ldpc = ldpc;
 289 }
 290 
 291 void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
 292                             struct rtw_tx_pkt_info *pkt_info,
 293                             struct ieee80211_tx_control *control,
 294                             struct sk_buff *skb)
 295 {
 296         struct rtw_chip_info *chip = rtwdev->chip;
 297         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 298         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 299         struct rtw_sta_info *si;
 300         struct ieee80211_vif *vif = NULL;
 301         __le16 fc = hdr->frame_control;
 302         u8 sec_type = 0;
 303         bool bmc;
 304 
 305         if (control->sta) {
 306                 si = (struct rtw_sta_info *)control->sta->drv_priv;
 307                 vif = si->vif;
 308         }
 309 
 310         if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
 311                 rtw_tx_mgmt_pkt_info_update(rtwdev, pkt_info, control, skb);
 312         else if (ieee80211_is_data(fc))
 313                 rtw_tx_data_pkt_info_update(rtwdev, pkt_info, control, skb);
 314 
 315         if (info->control.hw_key) {
 316                 struct ieee80211_key_conf *key = info->control.hw_key;
 317 
 318                 switch (key->cipher) {
 319                 case WLAN_CIPHER_SUITE_WEP40:
 320                 case WLAN_CIPHER_SUITE_WEP104:
 321                 case WLAN_CIPHER_SUITE_TKIP:
 322                         sec_type = 0x01;
 323                         break;
 324                 case WLAN_CIPHER_SUITE_CCMP:
 325                         sec_type = 0x03;
 326                         break;
 327                 default:
 328                         break;
 329                 }
 330         }
 331 
 332         bmc = is_broadcast_ether_addr(hdr->addr1) ||
 333               is_multicast_ether_addr(hdr->addr1);
 334 
 335         if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
 336                 rtw_tx_report_enable(rtwdev, pkt_info);
 337 
 338         pkt_info->bmc = bmc;
 339         pkt_info->sec_type = sec_type;
 340         pkt_info->tx_pkt_size = skb->len;
 341         pkt_info->offset = chip->tx_pkt_desc_sz;
 342         pkt_info->qsel = skb->priority;
 343         pkt_info->ls = true;
 344 
 345         /* maybe merge with tx status ? */
 346         rtw_tx_stats(rtwdev, vif, skb);
 347 }
 348 
 349 void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
 350                                    struct rtw_tx_pkt_info *pkt_info,
 351                                    struct sk_buff *skb)
 352 {
 353         struct rtw_chip_info *chip = rtwdev->chip;
 354         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 355         bool bmc;
 356 
 357         bmc = is_broadcast_ether_addr(hdr->addr1) ||
 358               is_multicast_ether_addr(hdr->addr1);
 359         pkt_info->use_rate = true;
 360         pkt_info->rate_id = 6;
 361         pkt_info->dis_rate_fallback = true;
 362         pkt_info->bmc = bmc;
 363         pkt_info->tx_pkt_size = skb->len;
 364         pkt_info->offset = chip->tx_pkt_desc_sz;
 365         pkt_info->qsel = TX_DESC_QSEL_MGMT;
 366         pkt_info->ls = true;
 367 }

/* [<][>][^][v][top][bottom][index][help] */