linux/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2012  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../usb.h"
   6#include "../ps.h"
   7#include "../base.h"
   8#include "reg.h"
   9#include "def.h"
  10#include "phy.h"
  11#include "rf.h"
  12#include "dm.h"
  13#include "mac.h"
  14#include "trx.h"
  15#include "../rtl8192c/fw_common.h"
  16
  17static int configvertoutep(struct ieee80211_hw *hw)
  18{
  19        u8 ep_cfg, txqsele;
  20        u8 ep_nums = 0;
  21
  22        struct rtl_priv *rtlpriv = rtl_priv(hw);
  23        struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
  24        struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
  25
  26        rtlusb->out_queue_sel = 0;
  27        ep_cfg = rtl_read_byte(rtlpriv, REG_TEST_SIE_OPTIONAL);
  28        ep_cfg = (ep_cfg & USB_TEST_EP_MASK) >> USB_TEST_EP_SHIFT;
  29        switch (ep_cfg) {
  30        case 0:         /* 2 bulk OUT, 1 bulk IN */
  31        case 3:
  32                rtlusb->out_queue_sel  = TX_SELE_HQ | TX_SELE_LQ;
  33                ep_nums = 2;
  34                break;
  35        case 1: /* 1 bulk IN/OUT => map all endpoint to Low queue */
  36        case 2: /* 1 bulk IN, 1 bulk OUT => map all endpoint to High queue */
  37                txqsele = rtl_read_byte(rtlpriv, REG_TEST_USB_TXQS);
  38                if (txqsele & 0x0F) /* /map all endpoint to High queue */
  39                        rtlusb->out_queue_sel =  TX_SELE_HQ;
  40                else if (txqsele&0xF0) /* map all endpoint to Low queue */
  41                        rtlusb->out_queue_sel =  TX_SELE_LQ;
  42                ep_nums = 1;
  43                break;
  44        default:
  45                break;
  46        }
  47        return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL;
  48}
  49
  50static int configvernoutep(struct ieee80211_hw *hw)
  51{
  52        u8 ep_cfg;
  53        u8 ep_nums = 0;
  54
  55        struct rtl_priv *rtlpriv = rtl_priv(hw);
  56        struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
  57        struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
  58
  59        rtlusb->out_queue_sel = 0;
  60        /* Normal and High queue */
  61        ep_cfg =  rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 1));
  62        if (ep_cfg & USB_NORMAL_SIE_EP_MASK) {
  63                rtlusb->out_queue_sel |= TX_SELE_HQ;
  64                ep_nums++;
  65        }
  66        if ((ep_cfg >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
  67                rtlusb->out_queue_sel |= TX_SELE_NQ;
  68                ep_nums++;
  69        }
  70        /* Low queue */
  71        ep_cfg =  rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 2));
  72        if (ep_cfg & USB_NORMAL_SIE_EP_MASK) {
  73                rtlusb->out_queue_sel |= TX_SELE_LQ;
  74                ep_nums++;
  75        }
  76        return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL;
  77}
  78
  79static void twooutepmapping(struct ieee80211_hw *hw, bool is_chip8,
  80                             bool  bwificfg, struct rtl_ep_map *ep_map)
  81{
  82        struct rtl_priv *rtlpriv = rtl_priv(hw);
  83
  84        if (bwificfg) { /* for WMM */
  85                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
  86                         "USB Chip-B & WMM Setting.....\n");
  87                ep_map->ep_mapping[RTL_TXQ_BE]  = 2;
  88                ep_map->ep_mapping[RTL_TXQ_BK]  = 3;
  89                ep_map->ep_mapping[RTL_TXQ_VI]  = 3;
  90                ep_map->ep_mapping[RTL_TXQ_VO] = 2;
  91                ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
  92                ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
  93                ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
  94        } else { /* typical setting */
  95                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
  96                         "USB typical Setting.....\n");
  97                ep_map->ep_mapping[RTL_TXQ_BE]  = 3;
  98                ep_map->ep_mapping[RTL_TXQ_BK]  = 3;
  99                ep_map->ep_mapping[RTL_TXQ_VI]  = 2;
 100                ep_map->ep_mapping[RTL_TXQ_VO]  = 2;
 101                ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
 102                ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
 103                ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
 104        }
 105}
 106
 107static void threeoutepmapping(struct ieee80211_hw *hw, bool  bwificfg,
 108                               struct rtl_ep_map *ep_map)
 109{
 110        struct rtl_priv *rtlpriv = rtl_priv(hw);
 111
 112        if (bwificfg) { /* for WMM */
 113                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 114                         "USB 3EP Setting for WMM.....\n");
 115                ep_map->ep_mapping[RTL_TXQ_BE]  = 5;
 116                ep_map->ep_mapping[RTL_TXQ_BK]  = 3;
 117                ep_map->ep_mapping[RTL_TXQ_VI]  = 3;
 118                ep_map->ep_mapping[RTL_TXQ_VO]  = 2;
 119                ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
 120                ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
 121                ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
 122        } else { /* typical setting */
 123                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 124                         "USB 3EP Setting for typical.....\n");
 125                ep_map->ep_mapping[RTL_TXQ_BE]  = 5;
 126                ep_map->ep_mapping[RTL_TXQ_BK]  = 5;
 127                ep_map->ep_mapping[RTL_TXQ_VI]  = 3;
 128                ep_map->ep_mapping[RTL_TXQ_VO]  = 2;
 129                ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
 130                ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
 131                ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
 132        }
 133}
 134
 135static void oneoutepmapping(struct ieee80211_hw *hw, struct rtl_ep_map *ep_map)
 136{
 137        ep_map->ep_mapping[RTL_TXQ_BE]  = 2;
 138        ep_map->ep_mapping[RTL_TXQ_BK]  = 2;
 139        ep_map->ep_mapping[RTL_TXQ_VI]  = 2;
 140        ep_map->ep_mapping[RTL_TXQ_VO] = 2;
 141        ep_map->ep_mapping[RTL_TXQ_MGT] = 2;
 142        ep_map->ep_mapping[RTL_TXQ_BCN] = 2;
 143        ep_map->ep_mapping[RTL_TXQ_HI]  = 2;
 144}
 145
 146static int _out_ep_mapping(struct ieee80211_hw *hw)
 147{
 148        int err = 0;
 149        bool ischipn, bwificfg = false;
 150        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 151        struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
 152        struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
 153        struct rtl_ep_map *ep_map = &(rtlusb->ep_map);
 154
 155        ischipn = IS_NORMAL_CHIP(rtlhal->version);
 156        switch (rtlusb->out_ep_nums) {
 157        case 2:
 158                twooutepmapping(hw, ischipn, bwificfg, ep_map);
 159                break;
 160        case 3:
 161                /* Test chip doesn't support three out EPs. */
 162                if (!ischipn) {
 163                        err  =  -EINVAL;
 164                        goto err_out;
 165                }
 166                threeoutepmapping(hw, ischipn, ep_map);
 167                break;
 168        case 1:
 169                oneoutepmapping(hw, ep_map);
 170                break;
 171        default:
 172                err  =  -EINVAL;
 173                break;
 174        }
 175err_out:
 176        return err;
 177
 178}
 179
 180/* endpoint mapping */
 181int  rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw)
 182{
 183        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 184        int error = 0;
 185
 186        if (likely(IS_NORMAL_CHIP(rtlhal->version)))
 187                error = configvernoutep(hw);
 188        else
 189                error = configvertoutep(hw);
 190        if (error)
 191                goto err_out;
 192        error = _out_ep_mapping(hw);
 193        if (error)
 194                goto err_out;
 195err_out:
 196        return error;
 197}
 198
 199u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
 200{
 201        u16 hw_queue_index;
 202
 203        if (unlikely(ieee80211_is_beacon(fc))) {
 204                hw_queue_index = RTL_TXQ_BCN;
 205                goto out;
 206        }
 207        if (ieee80211_is_mgmt(fc)) {
 208                hw_queue_index = RTL_TXQ_MGT;
 209                goto out;
 210        }
 211        switch (mac80211_queue_index) {
 212        case 0:
 213                hw_queue_index = RTL_TXQ_VO;
 214                break;
 215        case 1:
 216                hw_queue_index = RTL_TXQ_VI;
 217                break;
 218        case 2:
 219                hw_queue_index = RTL_TXQ_BE;
 220                break;
 221        case 3:
 222                hw_queue_index = RTL_TXQ_BK;
 223                break;
 224        default:
 225                hw_queue_index = RTL_TXQ_BE;
 226                WARN_ONCE(true, "rtl8192cu: QSLT_BE queue, skb_queue:%d\n",
 227                          mac80211_queue_index);
 228                break;
 229        }
 230out:
 231        return hw_queue_index;
 232}
 233
 234static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw,
 235                                         __le16 fc, u16 mac80211_queue_index)
 236{
 237        enum rtl_desc_qsel qsel;
 238        struct rtl_priv *rtlpriv = rtl_priv(hw);
 239
 240        if (unlikely(ieee80211_is_beacon(fc))) {
 241                qsel = QSLT_BEACON;
 242                goto out;
 243        }
 244        if (ieee80211_is_mgmt(fc)) {
 245                qsel = QSLT_MGNT;
 246                goto out;
 247        }
 248        switch (mac80211_queue_index) {
 249        case 0: /* VO */
 250                qsel = QSLT_VO;
 251                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
 252                         "VO queue, set qsel = 0x%x\n", QSLT_VO);
 253                break;
 254        case 1: /* VI */
 255                qsel = QSLT_VI;
 256                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
 257                         "VI queue, set qsel = 0x%x\n", QSLT_VI);
 258                break;
 259        case 3: /* BK */
 260                qsel = QSLT_BK;
 261                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
 262                         "BK queue, set qsel = 0x%x\n", QSLT_BK);
 263                break;
 264        case 2: /* BE */
 265        default:
 266                qsel = QSLT_BE;
 267                RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
 268                         "BE queue, set qsel = 0x%x\n", QSLT_BE);
 269                break;
 270        }
 271out:
 272        return qsel;
 273}
 274
 275/* =============================================================== */
 276
 277/*----------------------------------------------------------------------
 278 *
 279 *      Rx handler
 280 *
 281 *---------------------------------------------------------------------- */
 282bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
 283                           struct rtl_stats *stats,
 284                           struct ieee80211_rx_status *rx_status,
 285                           u8 *pdesc8, struct sk_buff *skb)
 286{
 287        struct rx_fwinfo_92c *p_drvinfo;
 288        struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc8;
 289        __le32 *pdesc = (__le32 *)pdesc8;
 290        u32 phystatus = get_rx_desc_phy_status(pdesc);
 291
 292        stats->length = (u16)get_rx_desc_pkt_len(pdesc);
 293        stats->rx_drvinfo_size = (u8)get_rx_desc_drvinfo_size(pdesc) *
 294                                 RX_DRV_INFO_SIZE_UNIT;
 295        stats->rx_bufshift = (u8)(get_rx_desc_shift(pdesc) & 0x03);
 296        stats->icv = (u16)get_rx_desc_icv(pdesc);
 297        stats->crc = (u16)get_rx_desc_crc32(pdesc);
 298        stats->hwerror = (stats->crc | stats->icv);
 299        stats->decrypted = !get_rx_desc_swdec(pdesc);
 300        stats->rate = (u8)get_rx_desc_rx_mcs(pdesc);
 301        stats->shortpreamble = (u16)get_rx_desc_splcp(pdesc);
 302        stats->isampdu = (bool)(get_rx_desc_paggr(pdesc) == 1);
 303        stats->isfirst_ampdu = (bool)((get_rx_desc_paggr(pdesc) == 1) &&
 304                                      (get_rx_desc_faggr(pdesc) == 1));
 305        stats->timestamp_low = get_rx_desc_tsfl(pdesc);
 306        stats->rx_is40mhzpacket = (bool)get_rx_desc_bw(pdesc);
 307        stats->is_ht = (bool)get_rx_desc_rx_ht(pdesc);
 308        rx_status->freq = hw->conf.chandef.chan->center_freq;
 309        rx_status->band = hw->conf.chandef.chan->band;
 310        if (get_rx_desc_crc32(pdesc))
 311                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 312        if (!get_rx_desc_swdec(pdesc))
 313                rx_status->flag |= RX_FLAG_DECRYPTED;
 314        if (get_rx_desc_bw(pdesc))
 315                rx_status->bw = RATE_INFO_BW_40;
 316        if (get_rx_desc_rx_ht(pdesc))
 317                rx_status->encoding = RX_ENC_HT;
 318        rx_status->flag |= RX_FLAG_MACTIME_START;
 319        if (stats->decrypted)
 320                rx_status->flag |= RX_FLAG_DECRYPTED;
 321        rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
 322                                                   false, stats->rate);
 323        rx_status->mactime = get_rx_desc_tsfl(pdesc);
 324        if (phystatus) {
 325                p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
 326                                                     stats->rx_bufshift);
 327                rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc,
 328                                                 p_drvinfo);
 329        }
 330        /*rx_status->qual = stats->signal; */
 331        rx_status->signal = stats->recvsignalpower + 10;
 332        return true;
 333}
 334
 335#define RTL_RX_DRV_INFO_UNIT            8
 336
 337static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
 338{
 339        struct ieee80211_rx_status *rx_status =
 340                 (struct ieee80211_rx_status *)IEEE80211_SKB_RXCB(skb);
 341        u32 skb_len, pkt_len, drvinfo_len;
 342        struct rtl_priv *rtlpriv = rtl_priv(hw);
 343        __le32 *rxdesc;
 344        struct rtl_stats stats = {
 345                .signal = 0,
 346                .rate = 0,
 347        };
 348        struct rx_fwinfo_92c *p_drvinfo;
 349        bool bv;
 350        __le16 fc;
 351        struct ieee80211_hdr *hdr;
 352
 353        memset(rx_status, 0, sizeof(*rx_status));
 354        rxdesc  = (__le32 *)skb->data;
 355        skb_len = skb->len;
 356        drvinfo_len = (get_rx_desc_drvinfo_size(rxdesc) * RTL_RX_DRV_INFO_UNIT);
 357        pkt_len         = get_rx_desc_pkt_len(rxdesc);
 358        /* TODO: Error recovery. drop this skb or something. */
 359        WARN_ON(skb_len < (pkt_len + RTL_RX_DESC_SIZE + drvinfo_len));
 360        stats.length = (u16)get_rx_desc_pkt_len(rxdesc);
 361        stats.rx_drvinfo_size = (u8)get_rx_desc_drvinfo_size(rxdesc) *
 362                                RX_DRV_INFO_SIZE_UNIT;
 363        stats.rx_bufshift = (u8)(get_rx_desc_shift(rxdesc) & 0x03);
 364        stats.icv = (u16)get_rx_desc_icv(rxdesc);
 365        stats.crc = (u16)get_rx_desc_crc32(rxdesc);
 366        stats.hwerror = (stats.crc | stats.icv);
 367        stats.decrypted = !get_rx_desc_swdec(rxdesc);
 368        stats.rate = (u8)get_rx_desc_rx_mcs(rxdesc);
 369        stats.shortpreamble = (u16)get_rx_desc_splcp(rxdesc);
 370        stats.isampdu = (bool)((get_rx_desc_paggr(rxdesc) == 1) &&
 371                               (get_rx_desc_faggr(rxdesc) == 1));
 372        stats.timestamp_low = get_rx_desc_tsfl(rxdesc);
 373        stats.rx_is40mhzpacket = (bool)get_rx_desc_bw(rxdesc);
 374        stats.is_ht = (bool)get_rx_desc_rx_ht(rxdesc);
 375        /* TODO: is center_freq changed when doing scan? */
 376        /* TODO: Shall we add protection or just skip those two step? */
 377        rx_status->freq = hw->conf.chandef.chan->center_freq;
 378        rx_status->band = hw->conf.chandef.chan->band;
 379        if (get_rx_desc_crc32(rxdesc))
 380                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 381        if (!get_rx_desc_swdec(rxdesc))
 382                rx_status->flag |= RX_FLAG_DECRYPTED;
 383        if (get_rx_desc_bw(rxdesc))
 384                rx_status->bw = RATE_INFO_BW_40;
 385        if (get_rx_desc_rx_ht(rxdesc))
 386                rx_status->encoding = RX_ENC_HT;
 387        /* Data rate */
 388        rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats.is_ht,
 389                                                   false, stats.rate);
 390        /*  There is a phy status after this rx descriptor. */
 391        if (get_rx_desc_phy_status(rxdesc)) {
 392                p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE);
 393                rtl92c_translate_rx_signal_stuff(hw, skb, &stats,
 394                                 (struct rx_desc_92c *)rxdesc, p_drvinfo);
 395        }
 396        skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE));
 397        hdr = (struct ieee80211_hdr *)(skb->data);
 398        fc = hdr->frame_control;
 399        bv = ieee80211_is_probe_resp(fc);
 400        if (bv)
 401                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 402                         "Got probe response frame\n");
 403        if (ieee80211_is_beacon(fc))
 404                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n");
 405        if (ieee80211_is_data(fc))
 406                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n");
 407        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 408                 "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n",
 409                 fc,
 410                 (u32)hdr->addr1[0], (u32)hdr->addr1[1],
 411                 (u32)hdr->addr1[2], (u32)hdr->addr1[3],
 412                 (u32)hdr->addr1[4], (u32)hdr->addr1[5]);
 413        ieee80211_rx(hw, skb);
 414}
 415
 416void  rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb)
 417{
 418        _rtl_rx_process(hw, skb);
 419}
 420
 421/*----------------------------------------------------------------------
 422 *
 423 *      Tx handler
 424 *
 425 *---------------------------------------------------------------------- */
 426void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff  *skb)
 427{
 428}
 429
 430int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
 431                         struct sk_buff *skb)
 432{
 433        return 0;
 434}
 435
 436struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *hw,
 437                                           struct sk_buff_head *list)
 438{
 439        return skb_dequeue(list);
 440}
 441
 442/*======================================== trx ===============================*/
 443
 444static void _rtl_fill_usb_tx_desc(__le32 *txdesc)
 445{
 446        set_tx_desc_own(txdesc, 1);
 447        set_tx_desc_last_seg(txdesc, 1);
 448        set_tx_desc_first_seg(txdesc, 1);
 449}
 450
 451/**
 452 *      For HW recovery information
 453 */
 454static void _rtl_tx_desc_checksum(__le32 *txdesc)
 455{
 456        __le16 *ptr = (__le16 *)txdesc;
 457        u16     checksum = 0;
 458        u32 index;
 459
 460        /* Clear first */
 461        set_tx_desc_tx_desc_checksum(txdesc, 0);
 462        for (index = 0; index < 16; index++)
 463                checksum = checksum ^ le16_to_cpu(*(ptr + index));
 464        set_tx_desc_tx_desc_checksum(txdesc, checksum);
 465}
 466
 467void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
 468                          struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 469                          u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
 470                          struct ieee80211_sta *sta,
 471                          struct sk_buff *skb,
 472                          u8 queue_index,
 473                          struct rtl_tcb_desc *tcb_desc)
 474{
 475        struct rtl_priv *rtlpriv = rtl_priv(hw);
 476        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 477        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 478        bool defaultadapter = true;
 479        u8 *qc = ieee80211_get_qos_ctl(hdr);
 480        u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
 481        u16 seq_number;
 482        __le16 fc = hdr->frame_control;
 483        u8 rate_flag = info->control.rates[0].flags;
 484        u16 pktlen = skb->len;
 485        enum rtl_desc_qsel fw_qsel = _rtl8192cu_mq_to_descq(hw, fc,
 486                                                skb_get_queue_mapping(skb));
 487        u8 *txdesc8;
 488        __le32 *txdesc;
 489
 490        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 491        rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 492        txdesc8 = skb_push(skb, RTL_TX_HEADER_SIZE);
 493        txdesc = (__le32 *)txdesc8;
 494        memset(txdesc, 0, RTL_TX_HEADER_SIZE);
 495        set_tx_desc_pkt_size(txdesc, pktlen);
 496        set_tx_desc_linip(txdesc, 0);
 497        set_tx_desc_pkt_offset(txdesc, RTL_DUMMY_OFFSET);
 498        set_tx_desc_offset(txdesc, RTL_TX_HEADER_SIZE);
 499        set_tx_desc_tx_rate(txdesc, tcb_desc->hw_rate);
 500        if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
 501                set_tx_desc_data_shortgi(txdesc, 1);
 502        if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
 503                    info->flags & IEEE80211_TX_CTL_AMPDU) {
 504                set_tx_desc_agg_enable(txdesc, 1);
 505                set_tx_desc_max_agg_num(txdesc, 0x14);
 506        } else {
 507                set_tx_desc_agg_break(txdesc, 1);
 508        }
 509        set_tx_desc_seq(txdesc, seq_number);
 510        set_tx_desc_rts_enable(txdesc,
 511                               ((tcb_desc->rts_enable &&
 512                                !tcb_desc->cts_enable) ? 1 : 0));
 513        set_tx_desc_hw_rts_enable(txdesc,
 514                                  ((tcb_desc->rts_enable ||
 515                                   tcb_desc->cts_enable) ? 1 : 0));
 516        set_tx_desc_cts2self(txdesc, ((tcb_desc->cts_enable) ? 1 : 0));
 517        set_tx_desc_rts_stbc(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
 518        set_tx_desc_rts_rate(txdesc, tcb_desc->rts_rate);
 519        set_tx_desc_rts_bw(txdesc, 0);
 520        set_tx_desc_rts_sc(txdesc, tcb_desc->rts_sc);
 521        set_tx_desc_rts_short(txdesc,
 522                              ((tcb_desc->rts_rate <= DESC_RATE54M) ?
 523                               (tcb_desc->rts_use_shortpreamble ? 1 : 0)
 524                               : (tcb_desc->rts_use_shortgi ? 1 : 0)));
 525        if (mac->bw_40) {
 526                if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
 527                        set_tx_desc_data_bw(txdesc, 1);
 528                        set_tx_desc_data_sc(txdesc, 3);
 529                } else if(rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH){
 530                        set_tx_desc_data_bw(txdesc, 1);
 531                        set_tx_desc_data_sc(txdesc, mac->cur_40_prime_sc);
 532                } else {
 533                        set_tx_desc_data_bw(txdesc, 0);
 534                        set_tx_desc_data_sc(txdesc, 0);
 535                }
 536        } else {
 537                set_tx_desc_data_bw(txdesc, 0);
 538                set_tx_desc_data_sc(txdesc, 0);
 539        }
 540        rcu_read_lock();
 541        sta = ieee80211_find_sta(mac->vif, mac->bssid);
 542        if (sta) {
 543                u8 ampdu_density = sta->ht_cap.ampdu_density;
 544
 545                set_tx_desc_ampdu_density(txdesc, ampdu_density);
 546        }
 547        rcu_read_unlock();
 548        if (info->control.hw_key) {
 549                struct ieee80211_key_conf *keyconf = info->control.hw_key;
 550
 551                switch (keyconf->cipher) {
 552                case WLAN_CIPHER_SUITE_WEP40:
 553                case WLAN_CIPHER_SUITE_WEP104:
 554                case WLAN_CIPHER_SUITE_TKIP:
 555                        set_tx_desc_sec_type(txdesc, 0x1);
 556                        break;
 557                case WLAN_CIPHER_SUITE_CCMP:
 558                        set_tx_desc_sec_type(txdesc, 0x3);
 559                        break;
 560                default:
 561                        set_tx_desc_sec_type(txdesc, 0x0);
 562                        break;
 563                }
 564        }
 565        set_tx_desc_pkt_id(txdesc, 0);
 566        set_tx_desc_queue_sel(txdesc, fw_qsel);
 567        set_tx_desc_data_rate_fb_limit(txdesc, 0x1F);
 568        set_tx_desc_rts_rate_fb_limit(txdesc, 0xF);
 569        set_tx_desc_disable_fb(txdesc, 0);
 570        set_tx_desc_use_rate(txdesc, tcb_desc->use_driver_rate ? 1 : 0);
 571        if (ieee80211_is_data_qos(fc)) {
 572                if (mac->rdg_en) {
 573                        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 574                                 "Enable RDG function\n");
 575                        set_tx_desc_rdg_enable(txdesc, 1);
 576                        set_tx_desc_htc(txdesc, 1);
 577                }
 578        }
 579        if (rtlpriv->dm.useramask) {
 580                set_tx_desc_rate_id(txdesc, tcb_desc->ratr_index);
 581                set_tx_desc_macid(txdesc, tcb_desc->mac_id);
 582        } else {
 583                set_tx_desc_rate_id(txdesc, 0xC + tcb_desc->ratr_index);
 584                set_tx_desc_macid(txdesc, tcb_desc->ratr_index);
 585        }
 586        if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
 587              ppsc->fwctrl_lps) {
 588                set_tx_desc_hwseq_en(txdesc, 1);
 589                set_tx_desc_pkt_id(txdesc, 8);
 590                if (!defaultadapter)
 591                        set_tx_desc_qos(txdesc, 1);
 592        }
 593        if (ieee80211_has_morefrags(fc))
 594                set_tx_desc_more_frag(txdesc, 1);
 595        if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
 596            is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
 597                set_tx_desc_bmc(txdesc, 1);
 598        _rtl_fill_usb_tx_desc(txdesc);
 599        _rtl_tx_desc_checksum(txdesc);
 600        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
 601}
 602
 603void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 *pdesc8,
 604                              u32 buffer_len, bool is_pspoll)
 605{
 606        __le32 *pdesc = (__le32 *)pdesc8;
 607
 608        /* Clear all status */
 609        memset(pdesc, 0, RTL_TX_HEADER_SIZE);
 610        set_tx_desc_first_seg(pdesc, 1); /* bFirstSeg; */
 611        set_tx_desc_last_seg(pdesc, 1); /* bLastSeg; */
 612        set_tx_desc_offset(pdesc, RTL_TX_HEADER_SIZE); /* Offset = 32 */
 613        set_tx_desc_pkt_size(pdesc, buffer_len); /* Buffer size + command hdr */
 614        set_tx_desc_queue_sel(pdesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */
 615        /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error
 616         * vlaue by Hw. */
 617        if (is_pspoll) {
 618                set_tx_desc_nav_use_hdr(pdesc, 1);
 619        } else {
 620                set_tx_desc_hwseq_en(pdesc, 1); /* Hw set sequence number */
 621                set_tx_desc_pkt_id(pdesc, BIT(3)); /* set bit3 to 1. */
 622        }
 623        set_tx_desc_use_rate(pdesc, 1); /* use data rate which is set by Sw */
 624        set_tx_desc_own(pdesc, 1);
 625        set_tx_desc_tx_rate(pdesc, DESC_RATE1M);
 626        _rtl_tx_desc_checksum(pdesc);
 627}
 628
 629void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
 630                             u8 *pdesc8, bool firstseg,
 631                             bool lastseg, struct sk_buff *skb)
 632{
 633        struct rtl_priv *rtlpriv = rtl_priv(hw);
 634        u8 fw_queue = QSLT_BEACON;
 635        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 636        __le16 fc = hdr->frame_control;
 637        __le32 *pdesc = (__le32 *)pdesc8;
 638
 639        memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE);
 640        if (firstseg)
 641                set_tx_desc_offset(pdesc, RTL_TX_HEADER_SIZE);
 642        set_tx_desc_tx_rate(pdesc, DESC_RATE1M);
 643        set_tx_desc_seq(pdesc, 0);
 644        set_tx_desc_linip(pdesc, 0);
 645        set_tx_desc_queue_sel(pdesc, fw_queue);
 646        set_tx_desc_first_seg(pdesc, 1);
 647        set_tx_desc_last_seg(pdesc, 1);
 648        set_tx_desc_rate_id(pdesc, 7);
 649        set_tx_desc_macid(pdesc, 0);
 650        set_tx_desc_own(pdesc, 1);
 651        set_tx_desc_pkt_size(pdesc, (u16)skb->len);
 652        set_tx_desc_first_seg(pdesc, 1);
 653        set_tx_desc_last_seg(pdesc, 1);
 654        set_tx_desc_offset(pdesc, 0x20);
 655        set_tx_desc_use_rate(pdesc, 1);
 656        if (!ieee80211_is_data_qos(fc)) {
 657                set_tx_desc_hwseq_en(pdesc, 1);
 658                set_tx_desc_pkt_id(pdesc, 8);
 659        }
 660        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content",
 661                      pdesc, RTL_TX_DESC_SIZE);
 662}
 663