linux/drivers/staging/rtl8188eu/core/rtw_xmit.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 *
  14 ******************************************************************************/
  15#define _RTW_XMIT_C_
  16
  17#include <osdep_service.h>
  18#include <drv_types.h>
  19#include <mon.h>
  20#include <wifi.h>
  21#include <osdep_intf.h>
  22#include <linux/vmalloc.h>
  23
  24static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
  25static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
  26
  27static void _init_txservq(struct tx_servq *ptxservq)
  28{
  29        INIT_LIST_HEAD(&ptxservq->tx_pending);
  30        _rtw_init_queue(&ptxservq->sta_pending);
  31        ptxservq->qcnt = 0;
  32}
  33
  34void    _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
  35{
  36        memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
  37        spin_lock_init(&psta_xmitpriv->lock);
  38        _init_txservq(&psta_xmitpriv->be_q);
  39        _init_txservq(&psta_xmitpriv->bk_q);
  40        _init_txservq(&psta_xmitpriv->vi_q);
  41        _init_txservq(&psta_xmitpriv->vo_q);
  42        INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
  43        INIT_LIST_HEAD(&psta_xmitpriv->apsd);
  44
  45}
  46
  47s32     _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
  48{
  49        int i;
  50        struct xmit_buf *pxmitbuf;
  51        struct xmit_frame *pxframe;
  52        int     res = _SUCCESS;
  53        u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
  54        u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
  55
  56
  57        /*  We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
  58
  59        spin_lock_init(&pxmitpriv->lock);
  60
  61        /*
  62        Please insert all the queue initializaiton using _rtw_init_queue below
  63        */
  64
  65        pxmitpriv->adapter = padapter;
  66
  67        _rtw_init_queue(&pxmitpriv->be_pending);
  68        _rtw_init_queue(&pxmitpriv->bk_pending);
  69        _rtw_init_queue(&pxmitpriv->vi_pending);
  70        _rtw_init_queue(&pxmitpriv->vo_pending);
  71        _rtw_init_queue(&pxmitpriv->bm_pending);
  72
  73        _rtw_init_queue(&pxmitpriv->free_xmit_queue);
  74
  75        /*
  76        Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
  77        and initialize free_xmit_frame below.
  78        Please also apply  free_txobj to link_up all the xmit_frames...
  79        */
  80
  81        pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
  82
  83        if (pxmitpriv->pallocated_frame_buf  == NULL) {
  84                pxmitpriv->pxmit_frame_buf = NULL;
  85                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_frame fail!\n"));
  86                res = _FAIL;
  87                goto exit;
  88        }
  89        pxmitpriv->pxmit_frame_buf = PTR_ALIGN(pxmitpriv->pallocated_frame_buf, 4);
  90        /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
  91        /*                                              ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */
  92
  93        pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
  94
  95        for (i = 0; i < NR_XMITFRAME; i++) {
  96                INIT_LIST_HEAD(&(pxframe->list));
  97
  98                pxframe->padapter = padapter;
  99                pxframe->frame_tag = NULL_FRAMETAG;
 100
 101                pxframe->pkt = NULL;
 102
 103                pxframe->buf_addr = NULL;
 104                pxframe->pxmitbuf = NULL;
 105
 106                list_add_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
 107
 108                pxframe++;
 109        }
 110
 111        pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
 112
 113        pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
 114
 115        /* init xmit_buf */
 116        _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
 117        _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
 118
 119        pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
 120
 121        if (pxmitpriv->pallocated_xmitbuf  == NULL) {
 122                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_buf fail!\n"));
 123                res = _FAIL;
 124                goto exit;
 125        }
 126
 127        pxmitpriv->pxmitbuf = PTR_ALIGN(pxmitpriv->pallocated_xmitbuf, 4);
 128        /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
 129        /*                                              ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */
 130
 131        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 132
 133        for (i = 0; i < NR_XMITBUFF; i++) {
 134                INIT_LIST_HEAD(&pxmitbuf->list);
 135
 136                pxmitbuf->priv_data = NULL;
 137                pxmitbuf->padapter = padapter;
 138                pxmitbuf->ext_tag = false;
 139
 140                /* Tx buf allocation may fail sometimes, so sleep and retry. */
 141                res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
 142                if (res == _FAIL) {
 143                        msleep(10);
 144                        res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
 145                        if (res == _FAIL)
 146                                goto exit;
 147                }
 148
 149                pxmitbuf->flags = XMIT_VO_QUEUE;
 150
 151                list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
 152                pxmitbuf++;
 153        }
 154
 155        pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
 156
 157        /*  Init xmit extension buff */
 158        _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
 159
 160        pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
 161
 162        if (pxmitpriv->pallocated_xmit_extbuf  == NULL) {
 163                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_extbuf fail!\n"));
 164                res = _FAIL;
 165                goto exit;
 166        }
 167
 168        pxmitpriv->pxmit_extbuf = PTR_ALIGN(pxmitpriv->pallocated_xmit_extbuf, 4);
 169
 170        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
 171
 172        for (i = 0; i < num_xmit_extbuf; i++) {
 173                INIT_LIST_HEAD(&pxmitbuf->list);
 174
 175                pxmitbuf->priv_data = NULL;
 176                pxmitbuf->padapter = padapter;
 177                pxmitbuf->ext_tag = true;
 178
 179                res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
 180                if (res == _FAIL) {
 181                        res = _FAIL;
 182                        goto exit;
 183                }
 184
 185                list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
 186                pxmitbuf++;
 187        }
 188
 189        pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
 190
 191        rtw_alloc_hwxmits(padapter);
 192        rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 193
 194        for (i = 0; i < 4; i++)
 195                pxmitpriv->wmm_para_seq[i] = i;
 196
 197        pxmitpriv->txirp_cnt = 1;
 198
 199        /* per AC pending irp */
 200        pxmitpriv->beq_cnt = 0;
 201        pxmitpriv->bkq_cnt = 0;
 202        pxmitpriv->viq_cnt = 0;
 203        pxmitpriv->voq_cnt = 0;
 204
 205        pxmitpriv->ack_tx = false;
 206        mutex_init(&pxmitpriv->ack_tx_mutex);
 207        rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
 208
 209        rtw_hal_init_xmit_priv(padapter);
 210
 211exit:
 212
 213
 214        return res;
 215}
 216
 217void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
 218{
 219        int i;
 220        struct adapter *padapter = pxmitpriv->adapter;
 221        struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
 222        struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 223        u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
 224        u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
 225
 226        if (pxmitpriv->pxmit_frame_buf == NULL)
 227                return;
 228
 229        for (i = 0; i < NR_XMITFRAME; i++) {
 230                rtw_os_xmit_complete(padapter, pxmitframe);
 231
 232                pxmitframe++;
 233        }
 234
 235        for (i = 0; i < NR_XMITBUFF; i++) {
 236                rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
 237                pxmitbuf++;
 238        }
 239
 240        vfree(pxmitpriv->pallocated_frame_buf);
 241        vfree(pxmitpriv->pallocated_xmitbuf);
 242
 243        /*  free xmit extension buff */
 244        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
 245        for (i = 0; i < num_xmit_extbuf; i++) {
 246                rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
 247                pxmitbuf++;
 248        }
 249
 250        if (pxmitpriv->pallocated_xmit_extbuf)
 251                vfree(pxmitpriv->pallocated_xmit_extbuf);
 252
 253        rtw_free_hwxmits(padapter);
 254
 255        mutex_destroy(&pxmitpriv->ack_tx_mutex);
 256}
 257
 258static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe)
 259{
 260        u32     sz;
 261        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 262        struct sta_info *psta = pattrib->psta;
 263        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
 264        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
 265
 266        if (pattrib->nr_frags != 1)
 267                sz = padapter->xmitpriv.frag_len;
 268        else /* no frag */
 269                sz = pattrib->last_txcmdsz;
 270
 271        /*  (1) RTS_Threshold is compared to the MPDU, not MSDU. */
 272        /*  (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
 273        /*              Other fragments are protected by previous fragment. */
 274        /*              So we only need to check the length of first fragment. */
 275        if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
 276                if (sz > padapter->registrypriv.rts_thresh) {
 277                        pattrib->vcs_mode = RTS_CTS;
 278                } else {
 279                        if (psta->rtsen)
 280                                pattrib->vcs_mode = RTS_CTS;
 281                        else if (psta->cts2self)
 282                                pattrib->vcs_mode = CTS_TO_SELF;
 283                        else
 284                                pattrib->vcs_mode = NONE_VCS;
 285                }
 286        } else {
 287                while (true) {
 288                        /* IOT action */
 289                        if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && pattrib->ampdu_en &&
 290                            (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
 291                                pattrib->vcs_mode = CTS_TO_SELF;
 292                                break;
 293                        }
 294
 295                        /* check ERP protection */
 296                        if (psta->rtsen || psta->cts2self) {
 297                                if (psta->rtsen)
 298                                        pattrib->vcs_mode = RTS_CTS;
 299                                else if (psta->cts2self)
 300                                        pattrib->vcs_mode = CTS_TO_SELF;
 301
 302                                break;
 303                        }
 304
 305                        /* check HT op mode */
 306                        if (pattrib->ht_en) {
 307                                u8 htopmode = pmlmeinfo->HT_protection;
 308                                if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) ||
 309                                    (!pmlmeext->cur_bwmode && htopmode == 3)) {
 310                                        pattrib->vcs_mode = RTS_CTS;
 311                                        break;
 312                                }
 313                        }
 314
 315                        /* check rts */
 316                        if (sz > padapter->registrypriv.rts_thresh) {
 317                                pattrib->vcs_mode = RTS_CTS;
 318                                break;
 319                        }
 320
 321                        /* to do list: check MIMO power save condition. */
 322
 323                        /* check AMPDU aggregation for TXOP */
 324                        if (pattrib->ampdu_en) {
 325                                pattrib->vcs_mode = RTS_CTS;
 326                                break;
 327                        }
 328
 329                        pattrib->vcs_mode = NONE_VCS;
 330                        break;
 331                }
 332        }
 333}
 334
 335static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
 336{
 337        /*if (psta->rtsen)
 338                pattrib->vcs_mode = RTS_CTS;
 339        else if (psta->cts2self)
 340                pattrib->vcs_mode = CTS_TO_SELF;
 341        else
 342                pattrib->vcs_mode = NONE_VCS;*/
 343
 344        pattrib->mdata = 0;
 345        pattrib->eosp = 0;
 346        pattrib->triggered = 0;
 347
 348        /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
 349        pattrib->qos_en = psta->qos_option;
 350
 351        pattrib->raid = psta->raid;
 352        pattrib->ht_en = psta->htpriv.ht_option;
 353        pattrib->bwmode = psta->htpriv.bwmode;
 354        pattrib->ch_offset = psta->htpriv.ch_offset;
 355        pattrib->sgi = psta->htpriv.sgi;
 356        pattrib->ampdu_en = false;
 357        pattrib->retry_ctrl = false;
 358}
 359
 360u8      qos_acm(u8 acm_mask, u8 priority)
 361{
 362        u8      change_priority = priority;
 363
 364        switch (priority) {
 365        case 0:
 366        case 3:
 367                if (acm_mask & BIT(1))
 368                        change_priority = 1;
 369                break;
 370        case 1:
 371        case 2:
 372                break;
 373        case 4:
 374        case 5:
 375                if (acm_mask & BIT(2))
 376                        change_priority = 0;
 377                break;
 378        case 6:
 379        case 7:
 380                if (acm_mask & BIT(3))
 381                        change_priority = 5;
 382                break;
 383        default:
 384                DBG_88E("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
 385                break;
 386        }
 387
 388        return change_priority;
 389}
 390
 391static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
 392{
 393        struct ethhdr etherhdr;
 394        struct iphdr ip_hdr;
 395        s32 user_prio = 0;
 396
 397        _rtw_open_pktfile(ppktfile->pkt, ppktfile);
 398        _rtw_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);
 399
 400        /*  get user_prio from IP hdr */
 401        if (pattrib->ether_type == 0x0800) {
 402                _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
 403/*              user_prio = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
 404                user_prio = ip_hdr.tos >> 5;
 405        } else if (pattrib->ether_type == ETH_P_PAE) {
 406                /*  "When priority processing of data frames is supported, */
 407                /*  a STA's SME should send EAPOL-Key frames at the highest priority." */
 408                user_prio = 7;
 409        }
 410
 411        pattrib->priority = user_prio;
 412        pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
 413        pattrib->subtype = WIFI_QOS_DATA_TYPE;
 414}
 415
 416static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib)
 417{
 418        struct pkt_file pktfile;
 419        struct sta_info *psta = NULL;
 420        struct ethhdr etherhdr;
 421
 422        int bmcast;
 423        struct sta_priv         *pstapriv = &padapter->stapriv;
 424        struct security_priv    *psecuritypriv = &padapter->securitypriv;
 425        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 426        struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
 427        int res = _SUCCESS;
 428
 429
 430        _rtw_open_pktfile(pkt, &pktfile);
 431        _rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN);
 432
 433        pattrib->ether_type = ntohs(etherhdr.h_proto);
 434
 435        memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
 436        memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
 437
 438        pattrib->pctrl = 0;
 439
 440        if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 441            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 442                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 443                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 444        } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 445                memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
 446                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 447        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 448                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 449                memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
 450        }
 451
 452        pattrib->pktlen = pktfile.pkt_len;
 453
 454        if (pattrib->ether_type == ETH_P_IP) {
 455                /*  The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
 456                /*  to prevent DHCP protocol fail */
 457                u8 tmp[24];
 458                _rtw_pktfile_read(&pktfile, &tmp[0], 24);
 459                pattrib->dhcp_pkt = 0;
 460                if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
 461                        if (pattrib->ether_type == ETH_P_IP) {/*  IP header */
 462                                if (((tmp[21] == 68) && (tmp[23] == 67)) ||
 463                                    ((tmp[21] == 67) && (tmp[23] == 68))) {
 464                                        /*  68 : UDP BOOTP client */
 465                                        /*  67 : UDP BOOTP server */
 466                                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("====================== update_attrib: get DHCP Packet\n"));
 467                                        /*  Use low rate to send DHCP packet. */
 468                                        pattrib->dhcp_pkt = 1;
 469                                }
 470                        }
 471                }
 472        } else if (pattrib->ether_type == ETH_P_PAE) {
 473                DBG_88E_LEVEL(_drv_info_, "send eapol packet\n");
 474        }
 475
 476        if ((pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
 477                rtw_set_scan_deny(padapter, 3000);
 478
 479        /*  If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
 480        if ((pattrib->ether_type == ETH_P_ARP) || (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
 481                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
 482
 483        bmcast = IS_MCAST(pattrib->ra);
 484
 485        /*  get sta_info */
 486        if (bmcast) {
 487                psta = rtw_get_bcmc_stainfo(padapter);
 488        } else {
 489                psta = rtw_get_stainfo(pstapriv, pattrib->ra);
 490                if (psta == NULL) { /*  if we cannot get psta => drrp the pkt */
 491                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra: %pM\n", (pattrib->ra)));
 492                        res = _FAIL;
 493                        goto exit;
 494                } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) && (!(psta->state & _FW_LINKED))) {
 495                        res = _FAIL;
 496                        goto exit;
 497                }
 498        }
 499
 500        if (psta) {
 501                pattrib->mac_id = psta->mac_id;
 502                /* DBG_88E("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */
 503                pattrib->psta = psta;
 504        } else {
 505                /*  if we cannot get psta => drop the pkt */
 506                RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:%pM\n", (pattrib->ra)));
 507                res = _FAIL;
 508                goto exit;
 509        }
 510
 511        pattrib->ack_policy = 0;
 512
 513        pattrib->hdrlen = WLAN_HDR_A3_LEN;
 514        pattrib->subtype = WIFI_DATA_TYPE;
 515        pattrib->priority = 0;
 516
 517        if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
 518                if (psta->qos_option)
 519                        set_qos(&pktfile, pattrib);
 520        } else {
 521                if (pqospriv->qos_option) {
 522                        set_qos(&pktfile, pattrib);
 523
 524                        if (pmlmepriv->acm_mask != 0)
 525                                pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
 526                }
 527        }
 528
 529        if (psta->ieee8021x_blocked) {
 530                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\n psta->ieee8021x_blocked == true\n"));
 531
 532                pattrib->encrypt = 0;
 533
 534                if ((pattrib->ether_type != ETH_P_PAE) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 535                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true,  pattrib->ether_type(%.4x) != ETH_P_PAE\n", pattrib->ether_type));
 536                        res = _FAIL;
 537                        goto exit;
 538                }
 539        } else {
 540                GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
 541
 542                switch (psecuritypriv->dot11AuthAlgrthm) {
 543                case dot11AuthAlgrthm_Open:
 544                case dot11AuthAlgrthm_Shared:
 545                case dot11AuthAlgrthm_Auto:
 546                        pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
 547                        break;
 548                case dot11AuthAlgrthm_8021X:
 549                        if (bmcast)
 550                                pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
 551                        else
 552                                pattrib->key_idx = 0;
 553                        break;
 554                default:
 555                        pattrib->key_idx = 0;
 556                        break;
 557                }
 558        }
 559
 560        switch (pattrib->encrypt) {
 561        case _WEP40_:
 562        case _WEP104_:
 563                pattrib->iv_len = 4;
 564                pattrib->icv_len = 4;
 565                break;
 566        case _TKIP_:
 567                pattrib->iv_len = 8;
 568                pattrib->icv_len = 4;
 569
 570                if (padapter->securitypriv.busetkipkey == _FAIL) {
 571                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
 572                                 ("\npadapter->securitypriv.busetkipkey(%d) == _FAIL drop packet\n",
 573                                 padapter->securitypriv.busetkipkey));
 574                        res = _FAIL;
 575                        goto exit;
 576                }
 577                break;
 578        case _AES_:
 579                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("pattrib->encrypt=%d (_AES_)\n", pattrib->encrypt));
 580                pattrib->iv_len = 8;
 581                pattrib->icv_len = 8;
 582                break;
 583        default:
 584                pattrib->iv_len = 0;
 585                pattrib->icv_len = 0;
 586                break;
 587        }
 588
 589        RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
 590                 ("update_attrib: encrypt=%d  securitypriv.sw_encrypt=%d\n",
 591                  pattrib->encrypt, padapter->securitypriv.sw_encrypt));
 592
 593        if (pattrib->encrypt &&
 594            (padapter->securitypriv.sw_encrypt || !psecuritypriv->hw_decrypted)) {
 595                pattrib->bswenc = true;
 596                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
 597                         ("update_attrib: encrypt=%d securitypriv.hw_decrypted=%d bswenc = true\n",
 598                          pattrib->encrypt, padapter->securitypriv.sw_encrypt));
 599        } else {
 600                pattrib->bswenc = false;
 601                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("update_attrib: bswenc = false\n"));
 602        }
 603
 604        update_attrib_phy_info(pattrib, psta);
 605
 606exit:
 607
 608
 609        return res;
 610}
 611
 612static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe)
 613{
 614        int curfragnum, length;
 615        u8      *pframe, *payload, mic[8];
 616        struct  mic_data micdata;
 617        struct  sta_info *stainfo;
 618        struct  pkt_attrib *pattrib = &pxmitframe->attrib;
 619        struct  security_priv   *psecuritypriv = &padapter->securitypriv;
 620        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 621        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 622        u8 hw_hdr_offset = 0;
 623        int bmcst = IS_MCAST(pattrib->ra);
 624
 625        if (pattrib->psta)
 626                stainfo = pattrib->psta;
 627        else
 628                stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
 629
 630
 631        hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
 632
 633        if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */
 634                /* encode mic code */
 635                if (stainfo != NULL) {
 636                        u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 637                                           0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 638                                           0x0, 0x0};
 639
 640                        pframe = pxmitframe->buf_addr + hw_hdr_offset;
 641
 642                        if (bmcst) {
 643                                if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16))
 644                                        return _FAIL;
 645                                /* start to calculate the mic code */
 646                                rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
 647                        } else {
 648                                if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16)) {
 649                                        /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey == 0\n"); */
 650                                        /* msleep(10); */
 651                                        return _FAIL;
 652                                }
 653                                /* start to calculate the mic code */
 654                                rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
 655                        }
 656
 657                        if (pframe[1]&1) {   /* ToDS == 1 */
 658                                rtw_secmicappend(&micdata, &pframe[16], 6);  /* DA */
 659                                if (pframe[1]&2)  /* From Ds == 1 */
 660                                        rtw_secmicappend(&micdata, &pframe[24], 6);
 661                                else
 662                                rtw_secmicappend(&micdata, &pframe[10], 6);
 663                        } else {        /* ToDS == 0 */
 664                                rtw_secmicappend(&micdata, &pframe[4], 6);   /* DA */
 665                                if (pframe[1]&2)  /* From Ds == 1 */
 666                                        rtw_secmicappend(&micdata, &pframe[16], 6);
 667                                else
 668                                        rtw_secmicappend(&micdata, &pframe[10], 6);
 669                        }
 670
 671                        if (pattrib->qos_en)
 672                                priority[0] = (u8)pxmitframe->attrib.priority;
 673
 674                        rtw_secmicappend(&micdata, &priority[0], 4);
 675
 676                        payload = pframe;
 677
 678                        for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
 679                                payload = (u8 *)round_up((size_t)(payload), 4);
 680                                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
 681                                         ("=== curfragnum=%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
 682                                         curfragnum, *payload, *(payload+1),
 683                                         *(payload+2), *(payload+3),
 684                                         *(payload+4), *(payload+5),
 685                                         *(payload+6), *(payload+7)));
 686
 687                                payload = payload+pattrib->hdrlen+pattrib->iv_len;
 688                                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
 689                                         ("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",
 690                                         curfragnum, pattrib->hdrlen, pattrib->iv_len));
 691                                if ((curfragnum+1) == pattrib->nr_frags) {
 692                                        length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
 693                                        rtw_secmicappend(&micdata, payload, length);
 694                                        payload = payload+length;
 695                                } else {
 696                                        length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
 697                                        rtw_secmicappend(&micdata, payload, length);
 698                                        payload = payload+length+pattrib->icv_len;
 699                                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum=%d length=%d pattrib->icv_len=%d", curfragnum, length, pattrib->icv_len));
 700                                }
 701                        }
 702                        rtw_secgetmic(&micdata, &(mic[0]));
 703                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: before add mic code!!!\n"));
 704                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: pattrib->last_txcmdsz=%d!!!\n", pattrib->last_txcmdsz));
 705                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: mic[0]=0x%.2x , mic[1]=0x%.2x , mic[2]= 0x%.2x, mic[3]=0x%.2x\n\
 706  mic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x , mic[7]= 0x%.2x !!!!\n",
 707                                mic[0], mic[1], mic[2], mic[3], mic[4], mic[5], mic[6], mic[7]));
 708                        /* add mic code  and add the mic code length in last_txcmdsz */
 709
 710                        memcpy(payload, &(mic[0]), 8);
 711                        pattrib->last_txcmdsz += 8;
 712
 713                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("\n ======== last pkt ========\n"));
 714                        payload = payload-pattrib->last_txcmdsz+8;
 715                        for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; curfragnum = curfragnum+8)
 716                                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
 717                                                 (" %.2x,  %.2x,  %.2x,  %.2x,  %.2x,  %.2x,  %.2x,  %.2x ",
 718                                                 *(payload+curfragnum), *(payload+curfragnum+1),
 719                                                 *(payload+curfragnum+2), *(payload+curfragnum+3),
 720                                                 *(payload+curfragnum+4), *(payload+curfragnum+5),
 721                                                 *(payload+curfragnum+6), *(payload+curfragnum+7)));
 722                        } else {
 723                                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic: rtw_get_stainfo==NULL!!!\n"));
 724                        }
 725        }
 726
 727
 728        return _SUCCESS;
 729}
 730
 731static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
 732{
 733        struct  pkt_attrib       *pattrib = &pxmitframe->attrib;
 734
 735
 736        if (pattrib->bswenc) {
 737                RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("### xmitframe_swencrypt\n"));
 738                switch (pattrib->encrypt) {
 739                case _WEP40_:
 740                case _WEP104_:
 741                        rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
 742                        break;
 743                case _TKIP_:
 744                        rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
 745                        break;
 746                case _AES_:
 747                        rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
 748                        break;
 749                default:
 750                        break;
 751                }
 752        } else {
 753                RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, ("### xmitframe_hwencrypt\n"));
 754        }
 755
 756
 757        return _SUCCESS;
 758}
 759
 760s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib)
 761{
 762        u16 *qc;
 763
 764        struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
 765        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 766        struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 767        u8 qos_option = false;
 768
 769        int res = _SUCCESS;
 770        __le16 *fctrl = &pwlanhdr->frame_control;
 771
 772        struct sta_info *psta;
 773
 774        int bmcst = IS_MCAST(pattrib->ra);
 775
 776
 777        if (pattrib->psta) {
 778                psta = pattrib->psta;
 779        } else {
 780                if (bmcst)
 781                        psta = rtw_get_bcmc_stainfo(padapter);
 782                else
 783                        psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
 784        }
 785
 786        memset(hdr, 0, WLANHDR_OFFSET);
 787
 788        SetFrameSubType(fctrl, pattrib->subtype);
 789
 790        if (pattrib->subtype & WIFI_DATA_TYPE) {
 791                if ((check_fwstate(pmlmepriv,  WIFI_STATION_STATE) == true)) {
 792                        /* to_ds = 1, fr_ds = 0; */
 793                        /* Data transfer to AP */
 794                        SetToDs(fctrl);
 795                        memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
 796                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 797                        memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
 798
 799                        if (pqospriv->qos_option)
 800                                qos_option = true;
 801                } else if (check_fwstate(pmlmepriv,  WIFI_AP_STATE)) {
 802                        /* to_ds = 0, fr_ds = 1; */
 803                        SetFrDs(fctrl);
 804                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 805                        memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
 806                        memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
 807
 808                        if (psta->qos_option)
 809                                qos_option = true;
 810                } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 811                           check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 812                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 813                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 814                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
 815
 816                        if (psta->qos_option)
 817                                qos_option = true;
 818                } else {
 819                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
 820                        res = _FAIL;
 821                        goto exit;
 822                }
 823
 824                if (pattrib->mdata)
 825                        SetMData(fctrl);
 826
 827                if (pattrib->encrypt)
 828                        SetPrivacy(fctrl);
 829
 830                if (qos_option) {
 831                        qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
 832
 833                        if (pattrib->priority)
 834                                SetPriority(qc, pattrib->priority);
 835
 836                        SetEOSP(qc, pattrib->eosp);
 837
 838                        SetAckpolicy(qc, pattrib->ack_policy);
 839                }
 840
 841                /* TODO: fill HT Control Field */
 842
 843                /* Update Seq Num will be handled by f/w */
 844                if (psta) {
 845                        psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
 846                        psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
 847
 848                        pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
 849
 850                        SetSeqNum(hdr, pattrib->seqnum);
 851
 852                        /* check if enable ampdu */
 853                        if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
 854                                if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
 855                                        pattrib->ampdu_en = true;
 856                        }
 857
 858                        /* re-check if enable ampdu by BA_starting_seqctrl */
 859                        if (pattrib->ampdu_en) {
 860                                u16 tx_seq;
 861
 862                                tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
 863
 864                                /* check BA_starting_seqctrl */
 865                                if (SN_LESS(pattrib->seqnum, tx_seq)) {
 866                                        pattrib->ampdu_en = false;/* AGG BK */
 867                                } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
 868                                        psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
 869
 870                                        pattrib->ampdu_en = true;/* AGG EN */
 871                                } else {
 872                                        psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
 873                                        pattrib->ampdu_en = true;/* AGG EN */
 874                                }
 875                        }
 876                }
 877        }
 878exit:
 879
 880        return res;
 881}
 882
 883s32 rtw_txframes_pending(struct adapter *padapter)
 884{
 885        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 886
 887        return (!list_empty(&pxmitpriv->be_pending.queue) ||
 888                        !list_empty(&pxmitpriv->bk_pending.queue) ||
 889                        !list_empty(&pxmitpriv->vi_pending.queue) ||
 890                        !list_empty(&pxmitpriv->vo_pending.queue));
 891}
 892
 893s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib)
 894{
 895        struct sta_info *psta;
 896        struct tx_servq *ptxservq;
 897        int priority = pattrib->priority;
 898
 899        psta = pattrib->psta;
 900
 901        switch (priority) {
 902        case 1:
 903        case 2:
 904                ptxservq = &(psta->sta_xmitpriv.bk_q);
 905                break;
 906        case 4:
 907        case 5:
 908                ptxservq = &(psta->sta_xmitpriv.vi_q);
 909                break;
 910        case 6:
 911        case 7:
 912                ptxservq = &(psta->sta_xmitpriv.vo_q);
 913                break;
 914        case 0:
 915        case 3:
 916        default:
 917                ptxservq = &(psta->sta_xmitpriv.be_q);
 918                break;
 919        }
 920
 921        return ptxservq->qcnt;
 922}
 923
 924/*
 925 * Calculate wlan 802.11 packet MAX size from pkt_attrib
 926 * This function doesn't consider fragment case
 927 */
 928u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
 929{
 930        u32     len = 0;
 931
 932        len = pattrib->hdrlen + pattrib->iv_len; /*  WLAN Header and IV */
 933        len += SNAP_SIZE + sizeof(u16); /*  LLC */
 934        len += pattrib->pktlen;
 935        if (pattrib->encrypt == _TKIP_)
 936                len += 8; /*  MIC */
 937        len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /*  ICV */
 938
 939        return len;
 940}
 941
 942/*
 943
 944This sub-routine will perform all the following:
 945
 9461. remove 802.3 header.
 9472. create wlan_header, based on the info in pxmitframe
 9483. append sta's iv/ext-iv
 9494. append LLC
 9505. move frag chunk from pframe to pxmitframe->mem
 9516. apply sw-encrypt, if necessary.
 952
 953*/
 954s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe)
 955{
 956        struct pkt_file pktfile;
 957        s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
 958        size_t addr;
 959        u8 *pframe, *mem_start;
 960        u8 hw_hdr_offset;
 961        struct sta_info         *psta;
 962        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
 963        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 964        u8 *pbuf_start;
 965        s32 bmcst = IS_MCAST(pattrib->ra);
 966        s32 res = _SUCCESS;
 967
 968
 969        psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
 970
 971        if (psta == NULL)
 972                return _FAIL;
 973
 974        if (pxmitframe->buf_addr == NULL) {
 975                DBG_88E("==> %s buf_addr == NULL\n", __func__);
 976                return _FAIL;
 977        }
 978
 979        pbuf_start = pxmitframe->buf_addr;
 980
 981        hw_hdr_offset =  TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
 982
 983        mem_start = pbuf_start +        hw_hdr_offset;
 984
 985        if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
 986                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"));
 987                DBG_88E("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n");
 988                res = _FAIL;
 989                goto exit;
 990        }
 991
 992        _rtw_open_pktfile(pkt, &pktfile);
 993        _rtw_pktfile_read(&pktfile, NULL, ETH_HLEN);
 994
 995        frg_inx = 0;
 996        frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
 997
 998        while (1) {
 999                llc_sz = 0;
1000
1001                mpdu_len = frg_len;
1002
1003                pframe = mem_start;
1004
1005                SetMFrag(mem_start);
1006
1007                pframe += pattrib->hdrlen;
1008                mpdu_len -= pattrib->hdrlen;
1009
1010                /* adding icv, if necessary... */
1011                if (pattrib->iv_len) {
1012                        switch (pattrib->encrypt) {
1013                        case _WEP40_:
1014                        case _WEP104_:
1015                                WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1016                                break;
1017                        case _TKIP_:
1018                                if (bmcst)
1019                                        TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1020                                else
1021                                        TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
1022                                break;
1023                        case _AES_:
1024                                if (bmcst)
1025                                        AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
1026                                else
1027                                        AES_IV(pattrib->iv, psta->dot11txpn, 0);
1028                                break;
1029                        }
1030
1031                        memcpy(pframe, pattrib->iv, pattrib->iv_len);
1032
1033                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
1034                                 ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
1035                                  padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3)));
1036
1037                        pframe += pattrib->iv_len;
1038
1039                        mpdu_len -= pattrib->iv_len;
1040                }
1041
1042                if (frg_inx == 0) {
1043                        llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1044                        pframe += llc_sz;
1045                        mpdu_len -= llc_sz;
1046                }
1047
1048                if ((pattrib->icv_len > 0) && (pattrib->bswenc))
1049                        mpdu_len -= pattrib->icv_len;
1050
1051                if (bmcst) {
1052                        /*  don't do fragment to broadcat/multicast packets */
1053                        mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
1054                } else {
1055                        mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
1056                }
1057
1058                pframe += mem_sz;
1059
1060                if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1061                        memcpy(pframe, pattrib->icv, pattrib->icv_len);
1062                        pframe += pattrib->icv_len;
1063                }
1064
1065                frg_inx++;
1066
1067                if (bmcst || rtw_endofpktfile(&pktfile)) {
1068                        pattrib->nr_frags = frg_inx;
1069
1070                        pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) +
1071                                                ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
1072
1073                        ClearMFrag(mem_start);
1074
1075                        break;
1076                } else {
1077                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __func__));
1078                }
1079
1080                addr = (size_t)(pframe);
1081
1082                mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset;
1083                memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1084        }
1085
1086        /* Frame is about to be encrypted. Forward it to the monitor first. */
1087        rtl88eu_mon_xmit_hook(padapter->pmondev, pxmitframe, frg_len);
1088
1089        if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
1090                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"));
1091                DBG_88E("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
1092                res = _FAIL;
1093                goto exit;
1094        }
1095
1096        xmitframe_swencrypt(padapter, pxmitframe);
1097
1098        if (!bmcst)
1099                update_attrib_vcs_info(padapter, pxmitframe);
1100        else
1101                pattrib->vcs_mode = NONE_VCS;
1102
1103exit:
1104
1105
1106        return res;
1107}
1108
1109/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
1110 * IEEE LLC/SNAP header contains 8 octets
1111 * First 3 octets comprise the LLC portion
1112 * SNAP portion, 5 octets, is divided into two fields:
1113 *      Organizationally Unique Identifier(OUI), 3 octets,
1114 *      type, defined by that organization, 2 octets.
1115 */
1116s32 rtw_put_snap(u8 *data, u16 h_proto)
1117{
1118        struct ieee80211_snap_hdr *snap;
1119        u8 *oui;
1120
1121
1122        snap = (struct ieee80211_snap_hdr *)data;
1123        snap->dsap = 0xaa;
1124        snap->ssap = 0xaa;
1125        snap->ctrl = 0x03;
1126
1127        if (h_proto == 0x8137 || h_proto == 0x80f3)
1128                oui = P802_1H_OUI;
1129        else
1130                oui = RFC1042_OUI;
1131
1132        snap->oui[0] = oui[0];
1133        snap->oui[1] = oui[1];
1134        snap->oui[2] = oui[2];
1135
1136        *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
1137
1138
1139        return SNAP_SIZE + sizeof(u16);
1140}
1141
1142void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len)
1143{
1144        uint    protection;
1145        u8      *perp;
1146        int      erp_len;
1147        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
1148        struct  registry_priv *pregistrypriv = &padapter->registrypriv;
1149
1150
1151        switch (pxmitpriv->vcs_setting) {
1152        case DISABLE_VCS:
1153                pxmitpriv->vcs = NONE_VCS;
1154                break;
1155        case ENABLE_VCS:
1156                break;
1157        case AUTO_VCS:
1158        default:
1159                perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
1160                if (perp == NULL) {
1161                        pxmitpriv->vcs = NONE_VCS;
1162                } else {
1163                        protection = (*(perp + 2)) & BIT(1);
1164                        if (protection) {
1165                                if (pregistrypriv->vcs_type == RTS_CTS)
1166                                        pxmitpriv->vcs = RTS_CTS;
1167                                else
1168                                        pxmitpriv->vcs = CTS_TO_SELF;
1169                        } else {
1170                                pxmitpriv->vcs = NONE_VCS;
1171                        }
1172                }
1173                break;
1174        }
1175
1176}
1177
1178void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz)
1179{
1180        struct sta_info *psta = NULL;
1181        struct stainfo_stats *pstats = NULL;
1182        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
1183        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1184
1185        if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) {
1186                pxmitpriv->tx_bytes += sz;
1187                pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num;
1188
1189                psta = pxmitframe->attrib.psta;
1190                if (psta) {
1191                        pstats = &psta->sta_stats;
1192                        pstats->tx_pkts += pxmitframe->agg_num;
1193                        pstats->tx_bytes += sz;
1194                }
1195        }
1196}
1197
1198struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
1199{
1200        unsigned long irql;
1201        struct xmit_buf *pxmitbuf;
1202        struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1203
1204        spin_lock_irqsave(&pfree_queue->lock, irql);
1205        pxmitbuf = list_first_entry_or_null(&pfree_queue->queue,
1206                                            struct xmit_buf, list);
1207        if (pxmitbuf) {
1208                list_del_init(&pxmitbuf->list);
1209                pxmitpriv->free_xmit_extbuf_cnt--;
1210                pxmitbuf->priv_data = NULL;
1211                /* pxmitbuf->ext_tag = true; */
1212                if (pxmitbuf->sctx) {
1213                        DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
1214                        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1215                }
1216        }
1217        spin_unlock_irqrestore(&pfree_queue->lock, irql);
1218
1219        return pxmitbuf;
1220}
1221
1222s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1223{
1224        unsigned long irql;
1225        struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1226
1227
1228        if (pxmitbuf == NULL)
1229                return _FAIL;
1230
1231        spin_lock_irqsave(&pfree_queue->lock, irql);
1232
1233        list_del_init(&pxmitbuf->list);
1234
1235        list_add_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
1236        pxmitpriv->free_xmit_extbuf_cnt++;
1237
1238        spin_unlock_irqrestore(&pfree_queue->lock, irql);
1239
1240
1241        return _SUCCESS;
1242}
1243
1244struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
1245{
1246        unsigned long irql;
1247        struct xmit_buf *pxmitbuf;
1248        struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1249
1250        /* DBG_88E("+rtw_alloc_xmitbuf\n"); */
1251
1252        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
1253        pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
1254                                            struct xmit_buf, list);
1255        if (pxmitbuf) {
1256                list_del_init(&pxmitbuf->list);
1257                pxmitpriv->free_xmitbuf_cnt--;
1258                pxmitbuf->priv_data = NULL;
1259                if (pxmitbuf->sctx) {
1260                        DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
1261                        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1262                }
1263        }
1264        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irql);
1265
1266        return pxmitbuf;
1267}
1268
1269s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1270{
1271        unsigned long irql;
1272        struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1273
1274        if (pxmitbuf == NULL)
1275                return _FAIL;
1276
1277        if (pxmitbuf->sctx) {
1278                DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
1279                rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
1280        }
1281
1282        if (pxmitbuf->ext_tag) {
1283                rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
1284        } else {
1285                spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
1286
1287                list_del_init(&pxmitbuf->list);
1288
1289                list_add_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
1290
1291                pxmitpriv->free_xmitbuf_cnt++;
1292                spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irql);
1293        }
1294
1295
1296        return _SUCCESS;
1297}
1298
1299/*
1300Calling context:
13011. OS_TXENTRY
13022. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
1303
1304If we turn on USE_RXTHREAD, then, no need for critical section.
1305Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
1306
1307Must be very very cautious...
1308
1309*/
1310
1311struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)
1312                                /* _queue *pfree_xmit_queue) */
1313{
1314        /*
1315                Please remember to use all the osdep_service api,
1316                and lock/unlock or _enter/_exit critical to protect
1317                pfree_xmit_queue
1318        */
1319        struct xmit_frame *pxframe;
1320        struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1321
1322        spin_lock_bh(&pfree_xmit_queue->lock);
1323        pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
1324                                           struct xmit_frame, list);
1325        if (!pxframe) {
1326                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1327                         ("rtw_alloc_xmitframe:%d\n",
1328                         pxmitpriv->free_xmitframe_cnt));
1329        } else {
1330                list_del_init(&pxframe->list);
1331
1332                /* default value setting */
1333                pxmitpriv->free_xmitframe_cnt--;
1334
1335                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1336                         ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n",
1337                         pxmitpriv->free_xmitframe_cnt));
1338
1339                pxframe->buf_addr = NULL;
1340                pxframe->pxmitbuf = NULL;
1341
1342                memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
1343                /* pxframe->attrib.psta = NULL; */
1344
1345                pxframe->frame_tag = DATA_FRAMETAG;
1346
1347                pxframe->pkt = NULL;
1348                pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
1349
1350                pxframe->agg_num = 1;
1351                pxframe->ack_report = 0;
1352        }
1353        spin_unlock_bh(&pfree_xmit_queue->lock);
1354
1355        return pxframe;
1356}
1357
1358s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
1359{
1360        struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1361        struct adapter *padapter = pxmitpriv->adapter;
1362        struct sk_buff *pndis_pkt = NULL;
1363
1364
1365        if (pxmitframe == NULL) {
1366                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("====== rtw_free_xmitframe():pxmitframe == NULL!!!!!!!!!!\n"));
1367                goto exit;
1368        }
1369
1370        spin_lock_bh(&pfree_xmit_queue->lock);
1371
1372        list_del_init(&pxmitframe->list);
1373
1374        if (pxmitframe->pkt) {
1375                pndis_pkt = pxmitframe->pkt;
1376                pxmitframe->pkt = NULL;
1377        }
1378
1379        list_add_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
1380
1381        pxmitpriv->free_xmitframe_cnt++;
1382        RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
1383
1384        spin_unlock_bh(&pfree_xmit_queue->lock);
1385
1386        if (pndis_pkt)
1387                rtw_os_pkt_complete(padapter, pndis_pkt);
1388
1389exit:
1390
1391
1392        return _SUCCESS;
1393}
1394
1395void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue)
1396{
1397        struct list_head *plist, *phead;
1398        struct  xmit_frame      *pxmitframe;
1399
1400
1401        spin_lock_bh(&(pframequeue->lock));
1402
1403        phead = get_list_head(pframequeue);
1404        plist = phead->next;
1405
1406        while (phead != plist) {
1407                pxmitframe = container_of(plist, struct xmit_frame, list);
1408
1409                plist = plist->next;
1410
1411                rtw_free_xmitframe(pxmitpriv, pxmitframe);
1412        }
1413        spin_unlock_bh(&(pframequeue->lock));
1414
1415}
1416
1417s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
1418{
1419        if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
1420                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
1421                         ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n"));
1422/*              pxmitframe->pkt = NULL; */
1423                return _FAIL;
1424        }
1425
1426        return _SUCCESS;
1427}
1428
1429static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, struct __queue *pframe_queue)
1430{
1431        struct list_head *xmitframe_plist, *xmitframe_phead;
1432        struct  xmit_frame      *pxmitframe = NULL;
1433
1434        xmitframe_phead = get_list_head(pframe_queue);
1435        xmitframe_plist = xmitframe_phead->next;
1436
1437        if (xmitframe_phead != xmitframe_plist) {
1438                pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
1439
1440                xmitframe_plist = xmitframe_plist->next;
1441
1442                list_del_init(&pxmitframe->list);
1443
1444                ptxservq->qcnt--;
1445        }
1446        return pxmitframe;
1447}
1448
1449struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, int entry)
1450{
1451        struct list_head *sta_plist, *sta_phead;
1452        struct hw_xmit *phwxmit;
1453        struct tx_servq *ptxservq = NULL;
1454        struct __queue *pframe_queue = NULL;
1455        struct xmit_frame *pxmitframe = NULL;
1456        struct adapter *padapter = pxmitpriv->adapter;
1457        struct registry_priv    *pregpriv = &padapter->registrypriv;
1458        int i, inx[4];
1459
1460
1461        inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
1462
1463        if (pregpriv->wifi_spec == 1) {
1464                int j;
1465
1466                for (j = 0; j < 4; j++)
1467                        inx[j] = pxmitpriv->wmm_para_seq[j];
1468        }
1469
1470        spin_lock_bh(&pxmitpriv->lock);
1471
1472        for (i = 0; i < entry; i++) {
1473                phwxmit = phwxmit_i + inx[i];
1474
1475                sta_phead = get_list_head(phwxmit->sta_queue);
1476                sta_plist = sta_phead->next;
1477
1478                while (sta_phead != sta_plist) {
1479                        ptxservq = container_of(sta_plist, struct tx_servq, tx_pending);
1480
1481                        pframe_queue = &ptxservq->sta_pending;
1482
1483                        pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
1484
1485                        if (pxmitframe) {
1486                                phwxmit->accnt--;
1487
1488                                /* Remove sta node when there are no pending packets. */
1489                                if (list_empty(&pframe_queue->queue)) /* must be done after get_next and before break */
1490                                        list_del_init(&ptxservq->tx_pending);
1491                                goto exit;
1492                        }
1493
1494                        sta_plist = sta_plist->next;
1495                }
1496        }
1497exit:
1498        spin_unlock_bh(&pxmitpriv->lock);
1499        return pxmitframe;
1500}
1501
1502struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, int up, u8 *ac)
1503{
1504        struct tx_servq *ptxservq;
1505
1506        switch (up) {
1507        case 1:
1508        case 2:
1509                ptxservq = &(psta->sta_xmitpriv.bk_q);
1510                *(ac) = 3;
1511                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BK\n"));
1512                break;
1513        case 4:
1514        case 5:
1515                ptxservq = &(psta->sta_xmitpriv.vi_q);
1516                *(ac) = 1;
1517                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VI\n"));
1518                break;
1519        case 6:
1520        case 7:
1521                ptxservq = &(psta->sta_xmitpriv.vo_q);
1522                *(ac) = 0;
1523                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : VO\n"));
1524                break;
1525        case 0:
1526        case 3:
1527        default:
1528                ptxservq = &(psta->sta_xmitpriv.be_q);
1529                *(ac) = 2;
1530                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending : BE\n"));
1531        break;
1532        }
1533
1534
1535        return ptxservq;
1536}
1537
1538/*
1539 * Will enqueue pxmitframe to the proper queue,
1540 * and indicate it to xx_pending list.....
1541 */
1542s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
1543{
1544        u8      ac_index;
1545        struct sta_info *psta;
1546        struct tx_servq *ptxservq;
1547        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
1548        struct sta_priv *pstapriv = &padapter->stapriv;
1549        struct hw_xmit  *phwxmits =  padapter->xmitpriv.hwxmits;
1550        int res = _SUCCESS;
1551
1552
1553        if (pattrib->psta)
1554                psta = pattrib->psta;
1555        else
1556                psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1557
1558        if (psta == NULL) {
1559                res = _FAIL;
1560                DBG_88E("rtw_xmit_classifier: psta == NULL\n");
1561                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_classifier: psta == NULL\n"));
1562                goto exit;
1563        }
1564
1565        ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
1566
1567        if (list_empty(&ptxservq->tx_pending))
1568                list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
1569
1570        list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
1571        ptxservq->qcnt++;
1572        phwxmits[ac_index].accnt++;
1573exit:
1574
1575
1576        return res;
1577}
1578
1579void rtw_alloc_hwxmits(struct adapter *padapter)
1580{
1581        struct hw_xmit *hwxmits;
1582        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1583
1584        pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
1585
1586        pxmitpriv->hwxmits = kcalloc(pxmitpriv->hwxmit_entry,
1587                                     sizeof(struct hw_xmit), GFP_KERNEL);
1588
1589        hwxmits = pxmitpriv->hwxmits;
1590
1591        hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
1592        hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
1593        hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
1594        hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
1595}
1596
1597void rtw_free_hwxmits(struct adapter *padapter)
1598{
1599        struct hw_xmit *hwxmits;
1600        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1601
1602        hwxmits = pxmitpriv->hwxmits;
1603        kfree(hwxmits);
1604}
1605
1606void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry)
1607{
1608        int i;
1609        for (i = 0; i < entry; i++, phwxmit++)
1610                phwxmit->accnt = 0;
1611}
1612
1613u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
1614{
1615        u32 addr;
1616        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1617
1618        switch (pattrib->qsel) {
1619        case 0:
1620        case 3:
1621                addr = BE_QUEUE_INX;
1622                break;
1623        case 1:
1624        case 2:
1625                addr = BK_QUEUE_INX;
1626                break;
1627        case 4:
1628        case 5:
1629                addr = VI_QUEUE_INX;
1630                break;
1631        case 6:
1632        case 7:
1633                addr = VO_QUEUE_INX;
1634                break;
1635        case 0x10:
1636                addr = BCN_QUEUE_INX;
1637                break;
1638        case 0x11:/* BC/MC in PS (HIQ) */
1639                addr = HIGH_QUEUE_INX;
1640                break;
1641        case 0x12:
1642        default:
1643                addr = MGT_QUEUE_INX;
1644                break;
1645        }
1646
1647        return addr;
1648}
1649
1650/*
1651 * The main transmit(tx) entry
1652 *
1653 * Return
1654 *      1       enqueue
1655 *      0       success, hardware will handle this xmit frame(packet)
1656 *      <0      fail
1657 */
1658s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
1659{
1660        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1661        struct xmit_frame *pxmitframe = NULL;
1662        s32 res;
1663
1664        pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
1665        if (pxmitframe == NULL) {
1666                RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: no more pxmitframe\n"));
1667                DBG_88E("DBG_TX_DROP_FRAME %s no more pxmitframe\n", __func__);
1668                return -1;
1669        }
1670
1671        res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
1672
1673        if (res == _FAIL) {
1674                RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: update attrib fail\n"));
1675                rtw_free_xmitframe(pxmitpriv, pxmitframe);
1676                return -1;
1677        }
1678        pxmitframe->pkt = *ppkt;
1679
1680        rtw_led_control(padapter, LED_CTL_TX);
1681
1682        pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
1683
1684#ifdef CONFIG_88EU_AP_MODE
1685        spin_lock_bh(&pxmitpriv->lock);
1686        if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe)) {
1687                spin_unlock_bh(&pxmitpriv->lock);
1688                return 1;
1689        }
1690        spin_unlock_bh(&pxmitpriv->lock);
1691#endif
1692
1693        if (rtw_hal_xmit(padapter, pxmitframe) == false)
1694                return 1;
1695
1696        return 0;
1697}
1698
1699#if defined(CONFIG_88EU_AP_MODE)
1700
1701int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe)
1702{
1703        int ret = false;
1704        struct sta_info *psta = NULL;
1705        struct sta_priv *pstapriv = &padapter->stapriv;
1706        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1707        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1708        int bmcst = IS_MCAST(pattrib->ra);
1709
1710        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false)
1711                return ret;
1712
1713        if (pattrib->psta)
1714                psta = pattrib->psta;
1715        else
1716                psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1717
1718        if (psta == NULL)
1719                return ret;
1720
1721        if (pattrib->triggered == 1) {
1722                if (bmcst)
1723                        pattrib->qsel = 0x11;/* HIQ */
1724                return ret;
1725        }
1726
1727        if (bmcst) {
1728                spin_lock_bh(&psta->sleep_q.lock);
1729
1730                if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */
1731                        list_del_init(&pxmitframe->list);
1732
1733                        list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
1734
1735                        psta->sleepq_len++;
1736
1737                        pstapriv->tim_bitmap |= BIT(0);/*  */
1738                        pstapriv->sta_dz_bitmap |= BIT(0);
1739
1740                        update_beacon(padapter, _TIM_IE_, NULL, false);/* tx bc/mc packets after update bcn */
1741
1742                        ret = true;
1743                }
1744
1745                spin_unlock_bh(&psta->sleep_q.lock);
1746
1747                return ret;
1748        }
1749
1750        spin_lock_bh(&psta->sleep_q.lock);
1751
1752        if (psta->state&WIFI_SLEEP_STATE) {
1753                u8 wmmps_ac = 0;
1754
1755                if (pstapriv->sta_dz_bitmap&BIT(psta->aid)) {
1756                        list_del_init(&pxmitframe->list);
1757
1758                        list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
1759
1760                        psta->sleepq_len++;
1761
1762                        switch (pattrib->priority) {
1763                        case 1:
1764                        case 2:
1765                                wmmps_ac = psta->uapsd_bk&BIT(0);
1766                                break;
1767                        case 4:
1768                        case 5:
1769                                wmmps_ac = psta->uapsd_vi&BIT(0);
1770                                break;
1771                        case 6:
1772                        case 7:
1773                                wmmps_ac = psta->uapsd_vo&BIT(0);
1774                                break;
1775                        case 0:
1776                        case 3:
1777                        default:
1778                                wmmps_ac = psta->uapsd_be&BIT(0);
1779                                break;
1780                        }
1781
1782                        if (wmmps_ac)
1783                                psta->sleepq_ac_len++;
1784
1785                        if (((psta->has_legacy_ac) && (!wmmps_ac)) ||
1786                            ((!psta->has_legacy_ac) && (wmmps_ac))) {
1787                                pstapriv->tim_bitmap |= BIT(psta->aid);
1788
1789                                if (psta->sleepq_len == 1) {
1790                                        /* update BCN for TIM IE */
1791                                        update_beacon(padapter, _TIM_IE_, NULL, false);
1792                                }
1793                        }
1794                        ret = true;
1795                }
1796        }
1797
1798        spin_unlock_bh(&psta->sleep_q.lock);
1799
1800        return ret;
1801}
1802
1803static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct __queue *pframequeue)
1804{
1805        struct list_head *plist, *phead;
1806        u8      ac_index;
1807        struct tx_servq *ptxservq;
1808        struct pkt_attrib       *pattrib;
1809        struct xmit_frame       *pxmitframe;
1810        struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
1811
1812        phead = get_list_head(pframequeue);
1813        plist = phead->next;
1814
1815        while (phead != plist) {
1816                pxmitframe = container_of(plist, struct xmit_frame, list);
1817
1818                plist = plist->next;
1819
1820                xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
1821
1822                pattrib = &pxmitframe->attrib;
1823
1824                ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
1825
1826                ptxservq->qcnt--;
1827                phwxmits[ac_index].accnt--;
1828        }
1829}
1830
1831void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
1832{
1833        struct sta_info *psta_bmc;
1834        struct sta_xmit_priv *pstaxmitpriv;
1835        struct sta_priv *pstapriv = &padapter->stapriv;
1836        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1837
1838        pstaxmitpriv = &psta->sta_xmitpriv;
1839
1840        /* for BC/MC Frames */
1841        psta_bmc = rtw_get_bcmc_stainfo(padapter);
1842
1843        spin_lock_bh(&pxmitpriv->lock);
1844
1845        psta->state |= WIFI_SLEEP_STATE;
1846
1847        pstapriv->sta_dz_bitmap |= BIT(psta->aid);
1848
1849        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
1850        list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
1851
1852        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
1853        list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
1854
1855        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
1856        list_del_init(&(pstaxmitpriv->be_q.tx_pending));
1857
1858        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
1859        list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
1860
1861        /* for BC/MC Frames */
1862        pstaxmitpriv = &psta_bmc->sta_xmitpriv;
1863        dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
1864        list_del_init(&(pstaxmitpriv->be_q.tx_pending));
1865
1866        spin_unlock_bh(&pxmitpriv->lock);
1867}
1868
1869void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
1870{
1871        u8 update_mask = 0, wmmps_ac = 0;
1872        struct sta_info *psta_bmc;
1873        struct list_head *xmitframe_plist, *xmitframe_phead;
1874        struct xmit_frame *pxmitframe = NULL;
1875        struct sta_priv *pstapriv = &padapter->stapriv;
1876
1877        spin_lock_bh(&psta->sleep_q.lock);
1878
1879        xmitframe_phead = get_list_head(&psta->sleep_q);
1880        xmitframe_plist = xmitframe_phead->next;
1881
1882        while (xmitframe_phead != xmitframe_plist) {
1883                pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
1884
1885                xmitframe_plist = xmitframe_plist->next;
1886
1887                list_del_init(&pxmitframe->list);
1888
1889                switch (pxmitframe->attrib.priority) {
1890                case 1:
1891                case 2:
1892                        wmmps_ac = psta->uapsd_bk&BIT(1);
1893                        break;
1894                case 4:
1895                case 5:
1896                        wmmps_ac = psta->uapsd_vi&BIT(1);
1897                        break;
1898                case 6:
1899                case 7:
1900                        wmmps_ac = psta->uapsd_vo&BIT(1);
1901                        break;
1902                case 0:
1903                case 3:
1904                default:
1905                        wmmps_ac = psta->uapsd_be&BIT(1);
1906                        break;
1907                }
1908
1909                psta->sleepq_len--;
1910                if (psta->sleepq_len > 0)
1911                        pxmitframe->attrib.mdata = 1;
1912                else
1913                        pxmitframe->attrib.mdata = 0;
1914
1915                if (wmmps_ac) {
1916                        psta->sleepq_ac_len--;
1917                        if (psta->sleepq_ac_len > 0) {
1918                                pxmitframe->attrib.mdata = 1;
1919                                pxmitframe->attrib.eosp = 0;
1920                        } else {
1921                                pxmitframe->attrib.mdata = 0;
1922                                pxmitframe->attrib.eosp = 1;
1923                        }
1924                }
1925
1926                pxmitframe->attrib.triggered = 1;
1927
1928                spin_unlock_bh(&psta->sleep_q.lock);
1929                if (rtw_hal_xmit(padapter, pxmitframe))
1930                        rtw_os_xmit_complete(padapter, pxmitframe);
1931                spin_lock_bh(&psta->sleep_q.lock);
1932        }
1933
1934        if (psta->sleepq_len == 0) {
1935                pstapriv->tim_bitmap &= ~BIT(psta->aid);
1936
1937                update_mask = BIT(0);
1938
1939                if (psta->state&WIFI_SLEEP_STATE)
1940                        psta->state ^= WIFI_SLEEP_STATE;
1941
1942                if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1943                        psta->expire_to = pstapriv->expire_to;
1944                        psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1945                }
1946
1947                pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
1948        }
1949
1950        spin_unlock_bh(&psta->sleep_q.lock);
1951
1952        /* for BC/MC Frames */
1953        psta_bmc = rtw_get_bcmc_stainfo(padapter);
1954        if (!psta_bmc)
1955                return;
1956
1957        if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) { /* no any sta in ps mode */
1958                spin_lock_bh(&psta_bmc->sleep_q.lock);
1959
1960                xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
1961                xmitframe_plist = xmitframe_phead->next;
1962
1963                while (xmitframe_phead != xmitframe_plist) {
1964                        pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
1965
1966                        xmitframe_plist = xmitframe_plist->next;
1967
1968                        list_del_init(&pxmitframe->list);
1969
1970                        psta_bmc->sleepq_len--;
1971                        if (psta_bmc->sleepq_len > 0)
1972                                pxmitframe->attrib.mdata = 1;
1973                        else
1974                                pxmitframe->attrib.mdata = 0;
1975
1976                        pxmitframe->attrib.triggered = 1;
1977
1978                        spin_unlock_bh(&psta_bmc->sleep_q.lock);
1979                        if (rtw_hal_xmit(padapter, pxmitframe))
1980                                rtw_os_xmit_complete(padapter, pxmitframe);
1981                        spin_lock_bh(&psta_bmc->sleep_q.lock);
1982                }
1983
1984                if (psta_bmc->sleepq_len == 0) {
1985                        pstapriv->tim_bitmap &= ~BIT(0);
1986                        pstapriv->sta_dz_bitmap &= ~BIT(0);
1987
1988                        update_mask |= BIT(1);
1989                }
1990
1991                spin_unlock_bh(&psta_bmc->sleep_q.lock);
1992        }
1993
1994        if (update_mask)
1995                update_beacon(padapter, _TIM_IE_, NULL, false);
1996}
1997
1998void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta)
1999{
2000        u8 wmmps_ac = 0;
2001        struct list_head *xmitframe_plist, *xmitframe_phead;
2002        struct xmit_frame *pxmitframe = NULL;
2003        struct sta_priv *pstapriv = &padapter->stapriv;
2004
2005        spin_lock_bh(&psta->sleep_q.lock);
2006
2007        xmitframe_phead = get_list_head(&psta->sleep_q);
2008        xmitframe_plist = xmitframe_phead->next;
2009
2010        while (xmitframe_phead != xmitframe_plist) {
2011                pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
2012
2013                xmitframe_plist = xmitframe_plist->next;
2014
2015                switch (pxmitframe->attrib.priority) {
2016                case 1:
2017                case 2:
2018                        wmmps_ac = psta->uapsd_bk&BIT(1);
2019                        break;
2020                case 4:
2021                case 5:
2022                        wmmps_ac = psta->uapsd_vi&BIT(1);
2023                        break;
2024                case 6:
2025                case 7:
2026                        wmmps_ac = psta->uapsd_vo&BIT(1);
2027                        break;
2028                case 0:
2029                case 3:
2030                default:
2031                        wmmps_ac = psta->uapsd_be&BIT(1);
2032                        break;
2033                }
2034
2035                if (!wmmps_ac)
2036                        continue;
2037
2038                list_del_init(&pxmitframe->list);
2039
2040                psta->sleepq_len--;
2041                psta->sleepq_ac_len--;
2042
2043                if (psta->sleepq_ac_len > 0) {
2044                        pxmitframe->attrib.mdata = 1;
2045                        pxmitframe->attrib.eosp = 0;
2046                } else {
2047                        pxmitframe->attrib.mdata = 0;
2048                        pxmitframe->attrib.eosp = 1;
2049                }
2050
2051                pxmitframe->attrib.triggered = 1;
2052
2053                if (rtw_hal_xmit(padapter, pxmitframe) == true)
2054                        rtw_os_xmit_complete(padapter, pxmitframe);
2055
2056                if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
2057                        pstapriv->tim_bitmap &= ~BIT(psta->aid);
2058
2059                        /* update BCN for TIM IE */
2060                        update_beacon(padapter, _TIM_IE_, NULL, false);
2061                }
2062        }
2063
2064        spin_unlock_bh(&psta->sleep_q.lock);
2065}
2066
2067#endif
2068
2069void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
2070{
2071        sctx->timeout_ms = timeout_ms;
2072        sctx->submit_time = jiffies;
2073        init_completion(&sctx->done);
2074        sctx->status = RTW_SCTX_SUBMITTED;
2075}
2076
2077int rtw_sctx_wait(struct submit_ctx *sctx)
2078{
2079        int ret = _FAIL;
2080        unsigned long expire;
2081        int status = 0;
2082
2083        expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
2084        if (!wait_for_completion_timeout(&sctx->done, expire)) {
2085                /* timeout, do something?? */
2086                status = RTW_SCTX_DONE_TIMEOUT;
2087                DBG_88E("%s timeout\n", __func__);
2088        } else {
2089                status = sctx->status;
2090        }
2091
2092        if (status == RTW_SCTX_DONE_SUCCESS)
2093                ret = _SUCCESS;
2094
2095        return ret;
2096}
2097
2098static bool rtw_sctx_chk_waring_status(int status)
2099{
2100        switch (status) {
2101        case RTW_SCTX_DONE_UNKNOWN:
2102        case RTW_SCTX_DONE_BUF_ALLOC:
2103        case RTW_SCTX_DONE_BUF_FREE:
2104
2105        case RTW_SCTX_DONE_DRV_STOP:
2106        case RTW_SCTX_DONE_DEV_REMOVE:
2107                return true;
2108        default:
2109                return false;
2110        }
2111}
2112
2113void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
2114{
2115        if (*sctx) {
2116                if (rtw_sctx_chk_waring_status(status))
2117                        DBG_88E("%s status:%d\n", __func__, status);
2118                (*sctx)->status = status;
2119                complete(&((*sctx)->done));
2120                *sctx = NULL;
2121        }
2122}
2123
2124int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
2125{
2126        struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2127
2128        pack_tx_ops->submit_time = jiffies;
2129        pack_tx_ops->timeout_ms = timeout_ms;
2130        pack_tx_ops->status = RTW_SCTX_SUBMITTED;
2131
2132        return rtw_sctx_wait(pack_tx_ops);
2133}
2134
2135void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
2136{
2137        struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2138
2139        if (pxmitpriv->ack_tx)
2140                rtw_sctx_done_err(&pack_tx_ops, status);
2141        else
2142                DBG_88E("%s ack_tx not set\n", __func__);
2143}
2144