linux/drivers/staging/rtl8712/rtl871x_xmit.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 * rtl871x_xmit.c
   4 *
   5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
   6 * Linux device driver for RTL8192SU
   7 *
   8 * Modifications for inclusion into the Linux staging tree are
   9 * Copyright(c) 2010 Larry Finger. All rights reserved.
  10 *
  11 * Contact information:
  12 * WLAN FAE <wlanfae@realtek.com>
  13 * Larry Finger <Larry.Finger@lwfinger.net>
  14 *
  15 ******************************************************************************/
  16
  17#define _RTL871X_XMIT_C_
  18
  19#include "osdep_service.h"
  20#include "drv_types.h"
  21#include "wifi.h"
  22#include "osdep_intf.h"
  23#include "usb_ops.h"
  24
  25
  26static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
  27static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
  28static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
  29static void alloc_hwxmits(struct _adapter *padapter);
  30static void free_hwxmits(struct _adapter *padapter);
  31
  32static void _init_txservq(struct tx_servq *ptxservq)
  33{
  34        INIT_LIST_HEAD(&ptxservq->tx_pending);
  35        _init_queue(&ptxservq->sta_pending);
  36        ptxservq->qcnt = 0;
  37}
  38
  39void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
  40{
  41        memset((unsigned char *)psta_xmitpriv, 0,
  42                 sizeof(struct sta_xmit_priv));
  43        spin_lock_init(&psta_xmitpriv->lock);
  44        _init_txservq(&psta_xmitpriv->be_q);
  45        _init_txservq(&psta_xmitpriv->bk_q);
  46        _init_txservq(&psta_xmitpriv->vi_q);
  47        _init_txservq(&psta_xmitpriv->vo_q);
  48        INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
  49        INIT_LIST_HEAD(&psta_xmitpriv->apsd);
  50}
  51
  52int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
  53                          struct _adapter *padapter)
  54{
  55        sint i;
  56        struct xmit_buf *pxmitbuf;
  57        struct xmit_frame *pxframe;
  58
  59        memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
  60        spin_lock_init(&pxmitpriv->lock);
  61        /*
  62         *Please insert all the queue initialization using _init_queue below
  63         */
  64        pxmitpriv->adapter = padapter;
  65        _init_queue(&pxmitpriv->be_pending);
  66        _init_queue(&pxmitpriv->bk_pending);
  67        _init_queue(&pxmitpriv->vi_pending);
  68        _init_queue(&pxmitpriv->vo_pending);
  69        _init_queue(&pxmitpriv->bm_pending);
  70        _init_queue(&pxmitpriv->legacy_dz_queue);
  71        _init_queue(&pxmitpriv->apsd_queue);
  72        _init_queue(&pxmitpriv->free_xmit_queue);
  73        /*
  74         * Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
  75         * and initialize free_xmit_frame below.
  76         * Please also apply  free_txobj to link_up all the xmit_frames...
  77         */
  78        pxmitpriv->pallocated_frame_buf =
  79                kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4, GFP_ATOMIC);
  80        if (!pxmitpriv->pallocated_frame_buf) {
  81                pxmitpriv->pxmit_frame_buf = NULL;
  82                return -ENOMEM;
  83        }
  84        pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
  85                        ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
  86        pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
  87        for (i = 0; i < NR_XMITFRAME; i++) {
  88                INIT_LIST_HEAD(&(pxframe->list));
  89                pxframe->padapter = padapter;
  90                pxframe->frame_tag = DATA_FRAMETAG;
  91                pxframe->pkt = NULL;
  92                pxframe->buf_addr = NULL;
  93                pxframe->pxmitbuf = NULL;
  94                list_add_tail(&(pxframe->list),
  95                                 &(pxmitpriv->free_xmit_queue.queue));
  96                pxframe++;
  97        }
  98        pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
  99        /*
 100         * init xmit hw_txqueue
 101         */
 102        _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
 103        _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
 104        _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
 105        _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
 106        _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
 107        pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
 108        pxmitpriv->txirp_cnt = 1;
 109        /*per AC pending irp*/
 110        pxmitpriv->beq_cnt = 0;
 111        pxmitpriv->bkq_cnt = 0;
 112        pxmitpriv->viq_cnt = 0;
 113        pxmitpriv->voq_cnt = 0;
 114        /*init xmit_buf*/
 115        _init_queue(&pxmitpriv->free_xmitbuf_queue);
 116        _init_queue(&pxmitpriv->pending_xmitbuf_queue);
 117        pxmitpriv->pallocated_xmitbuf =
 118                kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
 119        if (!pxmitpriv->pallocated_xmitbuf) {
 120                kfree(pxmitpriv->pallocated_frame_buf);
 121                pxmitpriv->pallocated_frame_buf = NULL;
 122                return -ENOMEM;
 123        }
 124        pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
 125                              ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
 126        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 127        for (i = 0; i < NR_XMITBUFF; i++) {
 128                INIT_LIST_HEAD(&pxmitbuf->list);
 129                pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ,
 130                                                   GFP_ATOMIC);
 131                if (!pxmitbuf->pallocated_buf)
 132                        return -ENOMEM;
 133                pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
 134                                 ((addr_t) (pxmitbuf->pallocated_buf) &
 135                                 (XMITBUF_ALIGN_SZ - 1));
 136                if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
 137                        return -ENOMEM;
 138                list_add_tail(&pxmitbuf->list,
 139                                 &(pxmitpriv->free_xmitbuf_queue.queue));
 140                pxmitbuf++;
 141        }
 142        pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
 143        INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter);
 144        alloc_hwxmits(padapter);
 145        init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 146        tasklet_init(&pxmitpriv->xmit_tasklet, r8712_xmit_bh,
 147                     (unsigned long)padapter);
 148        return 0;
 149}
 150
 151void _free_xmit_priv(struct xmit_priv *pxmitpriv)
 152{
 153        int i;
 154        struct _adapter *padapter = pxmitpriv->adapter;
 155        struct xmit_frame *pxmitframe = (struct xmit_frame *)
 156                                        pxmitpriv->pxmit_frame_buf;
 157        struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 158
 159        if (pxmitpriv->pxmit_frame_buf == NULL)
 160                return;
 161        for (i = 0; i < NR_XMITFRAME; i++) {
 162                r8712_xmit_complete(padapter, pxmitframe);
 163                pxmitframe++;
 164        }
 165        for (i = 0; i < NR_XMITBUFF; i++) {
 166                r8712_xmit_resource_free(padapter, pxmitbuf);
 167                kfree(pxmitbuf->pallocated_buf);
 168                pxmitbuf++;
 169        }
 170        kfree(pxmitpriv->pallocated_frame_buf);
 171        kfree(pxmitpriv->pallocated_xmitbuf);
 172        free_hwxmits(padapter);
 173}
 174
 175int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
 176                        struct pkt_attrib *pattrib)
 177{
 178        struct pkt_file pktfile;
 179        struct sta_info *psta = NULL;
 180        struct ethhdr etherhdr;
 181
 182        struct tx_cmd txdesc;
 183
 184        bool bmcast;
 185        struct sta_priv         *pstapriv = &padapter->stapriv;
 186        struct security_priv    *psecuritypriv = &padapter->securitypriv;
 187        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 188        struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
 189
 190        _r8712_open_pktfile(pkt, &pktfile);
 191
 192        _r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);
 193
 194        pattrib->ether_type = ntohs(etherhdr.h_proto);
 195
 196        /*
 197         * If driver xmit ARP packet, driver can set ps mode to initial
 198         * setting. It stands for getting DHCP or fix IP.
 199         */
 200        if (pattrib->ether_type == 0x0806) {
 201                if (padapter->pwrctrlpriv.pwr_mode !=
 202                    padapter->registrypriv.power_mgnt) {
 203                        del_timer_sync(&pmlmepriv->dhcp_timer);
 204                        r8712_set_ps_mode(padapter,
 205                                          padapter->registrypriv.power_mgnt,
 206                                          padapter->registrypriv.smart_ps);
 207                }
 208        }
 209
 210        memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
 211        memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
 212        pattrib->pctrl = 0;
 213        if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 214            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 215                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 216                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 217        } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 218                memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
 219                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 220        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 221                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 222                memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
 223        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 224                /*firstly, filter packet not belongs to mp*/
 225                if (pattrib->ether_type != 0x8712)
 226                        return -EINVAL;
 227                /* for mp storing the txcmd per packet,
 228                 * according to the info of txcmd to update pattrib
 229                 */
 230                /*get MP_TXDESC_SIZE bytes txcmd per packet*/
 231                _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
 232                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 233                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 234                pattrib->pctrl = 1;
 235        }
 236        /* r8712_xmitframe_coalesce() overwrite this!*/
 237        pattrib->pktlen = pktfile.pkt_len;
 238        if (pattrib->ether_type == ETH_P_IP) {
 239                /* The following is for DHCP and ARP packet, we use cck1M to
 240                 * tx these packets and let LPS awake some time
 241                 * to prevent DHCP protocol fail
 242                 */
 243                u8 tmp[24];
 244
 245                _r8712_pktfile_read(&pktfile, &tmp[0], 24);
 246                pattrib->dhcp_pkt = 0;
 247                if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
 248                        if (pattrib->ether_type == ETH_P_IP) {/* IP header*/
 249                                if (((tmp[21] == 68) && (tmp[23] == 67)) ||
 250                                        ((tmp[21] == 67) && (tmp[23] == 68))) {
 251                                        /* 68 : UDP BOOTP client
 252                                         * 67 : UDP BOOTP server
 253                                         * Use low rate to send DHCP packet.
 254                                         */
 255                                        pattrib->dhcp_pkt = 1;
 256                                }
 257                        }
 258                }
 259        }
 260        bmcast = is_multicast_ether_addr(pattrib->ra);
 261        /* get sta_info*/
 262        if (bmcast) {
 263                psta = r8712_get_bcmc_stainfo(padapter);
 264                pattrib->mac_id = 4;
 265        } else {
 266                if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 267                        psta = r8712_get_stainfo(pstapriv,
 268                                                 get_bssid(pmlmepriv));
 269                        pattrib->mac_id = 5;
 270                } else {
 271                        psta = r8712_get_stainfo(pstapriv, pattrib->ra);
 272                        if (psta == NULL)  /* drop the pkt */
 273                                return -ENOMEM;
 274                        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
 275                                pattrib->mac_id = 5;
 276                        else
 277                                pattrib->mac_id = psta->mac_id;
 278                }
 279        }
 280
 281        if (psta) {
 282                pattrib->psta = psta;
 283        } else {
 284                /* if we cannot get psta => drrp the pkt */
 285                return -ENOMEM;
 286        }
 287
 288        pattrib->ack_policy = 0;
 289        /* get ether_hdr_len */
 290        pattrib->pkt_hdrlen = ETH_HLEN;
 291
 292        if (pqospriv->qos_option) {
 293                r8712_set_qos(&pktfile, pattrib);
 294        } else {
 295                pattrib->hdrlen = WLAN_HDR_A3_LEN;
 296                pattrib->subtype = WIFI_DATA_TYPE;
 297                pattrib->priority = 0;
 298        }
 299        if (psta->ieee8021x_blocked) {
 300                pattrib->encrypt = 0;
 301                if ((pattrib->ether_type != 0x888e) &&
 302                    !check_fwstate(pmlmepriv, WIFI_MP_STATE))
 303                        return -EINVAL;
 304        } else {
 305                GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
 306        }
 307        switch (pattrib->encrypt) {
 308        case _WEP40_:
 309        case _WEP104_:
 310                pattrib->iv_len = 4;
 311                pattrib->icv_len = 4;
 312                break;
 313        case _TKIP_:
 314                pattrib->iv_len = 8;
 315                pattrib->icv_len = 4;
 316                if (padapter->securitypriv.busetkipkey == _FAIL)
 317                        return -EINVAL;
 318                break;
 319        case _AES_:
 320                pattrib->iv_len = 8;
 321                pattrib->icv_len = 8;
 322                break;
 323        default:
 324                pattrib->iv_len = 0;
 325                pattrib->icv_len = 0;
 326                break;
 327        }
 328
 329        if (pattrib->encrypt &&
 330            (padapter->securitypriv.sw_encrypt ||
 331            !psecuritypriv->hw_decrypted))
 332                pattrib->bswenc = true;
 333        else
 334                pattrib->bswenc = false;
 335        /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
 336         * some settings above.
 337         */
 338        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 339                pattrib->priority =
 340                    (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f;
 341        return 0;
 342}
 343
 344static int xmitframe_addmic(struct _adapter *padapter,
 345                            struct xmit_frame *pxmitframe)
 346{
 347        u32     curfragnum, length;
 348        u8      *pframe, *payload, mic[8];
 349        struct  mic_data micdata;
 350        struct  sta_info *stainfo;
 351        struct  qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
 352        struct  pkt_attrib  *pattrib = &pxmitframe->attrib;
 353        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 354        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 355        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 356        bool bmcst = is_multicast_ether_addr(pattrib->ra);
 357
 358        if (pattrib->psta)
 359                stainfo = pattrib->psta;
 360        else
 361                stainfo = r8712_get_stainfo(&padapter->stapriv,
 362                                            &pattrib->ra[0]);
 363        if (pattrib->encrypt == _TKIP_) {
 364                /*encode mic code*/
 365                if (stainfo != NULL) {
 366                        u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 367                                           0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 368                                           0x0, 0x0};
 369                        pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
 370                        if (bmcst) {
 371                                if (!memcmp(psecuritypriv->XGrptxmickey
 372                                   [psecuritypriv->XGrpKeyid].skey,
 373                                   null_key, 16))
 374                                        return -ENOMEM;
 375                                /*start to calculate the mic code*/
 376                                r8712_secmicsetkey(&micdata,
 377                                         psecuritypriv->
 378                                         XGrptxmickey[psecuritypriv->
 379                                        XGrpKeyid].skey);
 380                        } else {
 381                                if (!memcmp(&stainfo->tkiptxmickey.skey[0],
 382                                            null_key, 16))
 383                                        return -ENOMEM;
 384                                /* start to calculate the mic code */
 385                                r8712_secmicsetkey(&micdata,
 386                                             &stainfo->tkiptxmickey.skey[0]);
 387                        }
 388                        if (pframe[1] & 1) {   /* ToDS==1 */
 389                                r8712_secmicappend(&micdata,
 390                                                   &pframe[16], 6); /*DA*/
 391                                if (pframe[1] & 2)  /* From Ds==1 */
 392                                        r8712_secmicappend(&micdata,
 393                                                           &pframe[24], 6);
 394                                else
 395                                        r8712_secmicappend(&micdata,
 396                                                           &pframe[10], 6);
 397                        } else {        /* ToDS==0 */
 398                                r8712_secmicappend(&micdata,
 399                                                   &pframe[4], 6); /* DA */
 400                                if (pframe[1] & 2)  /* From Ds==1 */
 401                                        r8712_secmicappend(&micdata,
 402                                                           &pframe[16], 6);
 403                                else
 404                                        r8712_secmicappend(&micdata,
 405                                                           &pframe[10], 6);
 406                        }
 407                        if (pqospriv->qos_option == 1)
 408                                priority[0] = (u8)pxmitframe->attrib.priority;
 409                        r8712_secmicappend(&micdata, &priority[0], 4);
 410                        payload = pframe;
 411                        for (curfragnum = 0; curfragnum < pattrib->nr_frags;
 412                             curfragnum++) {
 413                                payload = (u8 *)RND4((addr_t)(payload));
 414                                payload += pattrib->hdrlen + pattrib->iv_len;
 415                                if ((curfragnum + 1) == pattrib->nr_frags) {
 416                                        length = pattrib->last_txcmdsz -
 417                                                  pattrib->hdrlen -
 418                                                  pattrib->iv_len -
 419                                                  ((psecuritypriv->sw_encrypt)
 420                                                  ? pattrib->icv_len : 0);
 421                                        r8712_secmicappend(&micdata, payload,
 422                                                           length);
 423                                        payload = payload + length;
 424                                } else {
 425                                        length = pxmitpriv->frag_len -
 426                                            pattrib->hdrlen - pattrib->iv_len -
 427                                            ((psecuritypriv->sw_encrypt) ?
 428                                            pattrib->icv_len : 0);
 429                                        r8712_secmicappend(&micdata, payload,
 430                                                           length);
 431                                        payload = payload + length +
 432                                                  pattrib->icv_len;
 433                                }
 434                        }
 435                        r8712_secgetmic(&micdata, &(mic[0]));
 436                        /* add mic code  and add the mic code length in
 437                         * last_txcmdsz
 438                         */
 439                        memcpy(payload, &(mic[0]), 8);
 440                        pattrib->last_txcmdsz += 8;
 441                        payload = payload - pattrib->last_txcmdsz + 8;
 442                }
 443        }
 444        return 0;
 445}
 446
 447static sint xmitframe_swencrypt(struct _adapter *padapter,
 448                                struct xmit_frame *pxmitframe)
 449{
 450        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 451
 452        if (pattrib->bswenc) {
 453                switch (pattrib->encrypt) {
 454                case _WEP40_:
 455                case _WEP104_:
 456                        r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
 457                        break;
 458                case _TKIP_:
 459                        r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
 460                        break;
 461                case _AES_:
 462                        r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
 463                        break;
 464                default:
 465                                break;
 466                }
 467        }
 468        return _SUCCESS;
 469}
 470
 471static int make_wlanhdr(struct _adapter *padapter, u8 *hdr,
 472                        struct pkt_attrib *pattrib)
 473{
 474        u16 *qc;
 475
 476        struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
 477        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 478        struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 479        __le16 *fctrl = &pwlanhdr->frame_ctl;
 480
 481        memset(hdr, 0, WLANHDR_OFFSET);
 482        SetFrameSubType(fctrl, pattrib->subtype);
 483        if (pattrib->subtype & WIFI_DATA_TYPE) {
 484                if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
 485                        /* to_ds = 1, fr_ds = 0; */
 486                        SetToDs(fctrl);
 487                        memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
 488                                ETH_ALEN);
 489                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 490                        memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
 491                } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 492                        /* to_ds = 0, fr_ds = 1; */
 493                        SetFrDs(fctrl);
 494                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 495                        memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
 496                                ETH_ALEN);
 497                        memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
 498                } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 499                           check_fwstate(pmlmepriv,
 500                                         WIFI_ADHOC_MASTER_STATE)) {
 501                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 502                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 503                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
 504                                ETH_ALEN);
 505                } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 506                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 507                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 508                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
 509                                ETH_ALEN);
 510                } else {
 511                        return -EINVAL;
 512                }
 513
 514                if (pattrib->encrypt)
 515                        SetPrivacy(fctrl);
 516                if (pqospriv->qos_option) {
 517                        qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
 518                        if (pattrib->priority)
 519                                SetPriority(qc, pattrib->priority);
 520                        SetAckpolicy(qc, pattrib->ack_policy);
 521                }
 522                /* TODO: fill HT Control Field */
 523                /* Update Seq Num will be handled by f/w */
 524                {
 525                        struct sta_info *psta;
 526                        bool bmcst = is_multicast_ether_addr(pattrib->ra);
 527
 528                        if (pattrib->psta) {
 529                                psta = pattrib->psta;
 530                        } else {
 531                                if (bmcst)
 532                                        psta = r8712_get_bcmc_stainfo(padapter);
 533                                else
 534                                        psta =
 535                                         r8712_get_stainfo(&padapter->stapriv,
 536                                         pattrib->ra);
 537                        }
 538                        if (psta) {
 539                                psta->sta_xmitpriv.txseq_tid
 540                                                  [pattrib->priority]++;
 541                                psta->sta_xmitpriv.txseq_tid[pattrib->priority]
 542                                                   &= 0xFFF;
 543                                pattrib->seqnum = psta->sta_xmitpriv.
 544                                                  txseq_tid[pattrib->priority];
 545                                SetSeqNum(hdr, pattrib->seqnum);
 546                        }
 547                }
 548        }
 549        return 0;
 550}
 551
 552static sint r8712_put_snap(u8 *data, u16 h_proto)
 553{
 554        struct ieee80211_snap_hdr *snap;
 555        const u8 *oui;
 556
 557        snap = (struct ieee80211_snap_hdr *)data;
 558        snap->dsap = 0xaa;
 559        snap->ssap = 0xaa;
 560        snap->ctrl = 0x03;
 561        if (h_proto == 0x8137 || h_proto == 0x80f3)
 562                oui = P802_1H_OUI;
 563        else
 564                oui = RFC1042_OUI;
 565        snap->oui[0] = oui[0];
 566        snap->oui[1] = oui[1];
 567        snap->oui[2] = oui[2];
 568        *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
 569        return SNAP_SIZE + sizeof(u16);
 570}
 571
 572/*
 573 * This sub-routine will perform all the following:
 574 * 1. remove 802.3 header.
 575 * 2. create wlan_header, based on the info in pxmitframe
 576 * 3. append sta's iv/ext-iv
 577 * 4. append LLC
 578 * 5. move frag chunk from pframe to pxmitframe->mem
 579 * 6. apply sw-encrypt, if necessary.
 580 */
 581sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
 582                        struct xmit_frame *pxmitframe)
 583{
 584        struct pkt_file pktfile;
 585
 586        sint    frg_len, mpdu_len, llc_sz;
 587        u32     mem_sz;
 588        u8      frg_inx;
 589        addr_t addr;
 590        u8 *pframe, *mem_start, *ptxdesc;
 591        struct sta_info         *psta;
 592        struct security_priv    *psecuritypriv = &padapter->securitypriv;
 593        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 594        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
 595        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 596        u8 *pbuf_start;
 597        bool bmcst = is_multicast_ether_addr(pattrib->ra);
 598
 599        if (pattrib->psta == NULL)
 600                return _FAIL;
 601        psta = pattrib->psta;
 602        if (pxmitframe->buf_addr == NULL)
 603                return _FAIL;
 604        pbuf_start = pxmitframe->buf_addr;
 605        ptxdesc = pbuf_start;
 606        mem_start = pbuf_start + TXDESC_OFFSET;
 607        if (make_wlanhdr(padapter, mem_start, pattrib))
 608                return _FAIL;
 609        _r8712_open_pktfile(pkt, &pktfile);
 610        _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
 611        if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 612                /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
 613                if (pattrib->ether_type == 0x8712) {
 614                        /* take care -  update_txdesc overwrite this */
 615                        _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
 616                }
 617        }
 618        pattrib->pktlen = pktfile.pkt_len;
 619        frg_inx = 0;
 620        frg_len = pxmitpriv->frag_len - 4;
 621        while (1) {
 622                llc_sz = 0;
 623                mpdu_len = frg_len;
 624                pframe = mem_start;
 625                SetMFrag(mem_start);
 626                pframe += pattrib->hdrlen;
 627                mpdu_len -= pattrib->hdrlen;
 628                /* adding icv, if necessary...*/
 629                if (pattrib->iv_len) {
 630                        if (psta != NULL) {
 631                                switch (pattrib->encrypt) {
 632                                case _WEP40_:
 633                                case _WEP104_:
 634                                        WEP_IV(pattrib->iv, psta->txpn,
 635                                               (u8)psecuritypriv->
 636                                               PrivacyKeyIndex);
 637                                        break;
 638                                case _TKIP_:
 639                                        if (bmcst)
 640                                                TKIP_IV(pattrib->iv,
 641                                                    psta->txpn,
 642                                                    (u8)psecuritypriv->
 643                                                    XGrpKeyid);
 644                                        else
 645                                                TKIP_IV(pattrib->iv, psta->txpn,
 646                                                        0);
 647                                        break;
 648                                case _AES_:
 649                                        if (bmcst)
 650                                                AES_IV(pattrib->iv, psta->txpn,
 651                                                    (u8)psecuritypriv->
 652                                                    XGrpKeyid);
 653                                        else
 654                                                AES_IV(pattrib->iv, psta->txpn,
 655                                                       0);
 656                                        break;
 657                                }
 658                        }
 659                        memcpy(pframe, pattrib->iv, pattrib->iv_len);
 660                        pframe += pattrib->iv_len;
 661                        mpdu_len -= pattrib->iv_len;
 662                }
 663                if (frg_inx == 0) {
 664                        llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
 665                        pframe += llc_sz;
 666                        mpdu_len -= llc_sz;
 667                }
 668                if ((pattrib->icv_len > 0) && (pattrib->bswenc))
 669                        mpdu_len -= pattrib->icv_len;
 670                if (bmcst)
 671                        mem_sz = _r8712_pktfile_read(&pktfile, pframe,
 672                                 pattrib->pktlen);
 673                else
 674                        mem_sz = _r8712_pktfile_read(&pktfile, pframe,
 675                                 mpdu_len);
 676                pframe += mem_sz;
 677                if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
 678                        memcpy(pframe, pattrib->icv, pattrib->icv_len);
 679                        pframe += pattrib->icv_len;
 680                }
 681                frg_inx++;
 682                if (bmcst || r8712_endofpktfile(&pktfile)) {
 683                        pattrib->nr_frags = frg_inx;
 684                        pattrib->last_txcmdsz = pattrib->hdrlen +
 685                                                pattrib->iv_len +
 686                                                ((pattrib->nr_frags == 1) ?
 687                                                llc_sz : 0) +
 688                                                ((pattrib->bswenc) ?
 689                                                pattrib->icv_len : 0) + mem_sz;
 690                        ClearMFrag(mem_start);
 691                        break;
 692                }
 693                addr = (addr_t)(pframe);
 694                mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
 695                memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
 696        }
 697
 698        if (xmitframe_addmic(padapter, pxmitframe))
 699                return _FAIL;
 700        xmitframe_swencrypt(padapter, pxmitframe);
 701        return _SUCCESS;
 702}
 703
 704void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
 705{
 706        uint    protection;
 707        u8      *perp;
 708        uint    erp_len;
 709        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 710        struct  registry_priv *pregistrypriv = &padapter->registrypriv;
 711
 712        switch (pxmitpriv->vcs_setting) {
 713        case DISABLE_VCS:
 714                pxmitpriv->vcs = NONE_VCS;
 715                break;
 716        case ENABLE_VCS:
 717                break;
 718        case AUTO_VCS:
 719        default:
 720                perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
 721                if (perp == NULL) {
 722                        pxmitpriv->vcs = NONE_VCS;
 723                } else {
 724                        protection = (*(perp + 2)) & BIT(1);
 725                        if (protection) {
 726                                if (pregistrypriv->vcs_type == RTS_CTS)
 727                                        pxmitpriv->vcs = RTS_CTS;
 728                                else
 729                                        pxmitpriv->vcs = CTS_TO_SELF;
 730                        } else {
 731                                pxmitpriv->vcs = NONE_VCS;
 732                        }
 733                }
 734                break;
 735        }
 736}
 737
 738struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
 739{
 740        unsigned long irqL;
 741        struct xmit_buf *pxmitbuf;
 742        struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 743
 744        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
 745        pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
 746                                            struct xmit_buf, list);
 747        if (pxmitbuf) {
 748                list_del_init(&pxmitbuf->list);
 749                pxmitpriv->free_xmitbuf_cnt--;
 750        }
 751        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
 752        return pxmitbuf;
 753}
 754
 755void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
 756{
 757        unsigned long irqL;
 758        struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 759
 760        if (pxmitbuf == NULL)
 761                return;
 762        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
 763        list_del_init(&pxmitbuf->list);
 764        list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
 765        pxmitpriv->free_xmitbuf_cnt++;
 766        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
 767}
 768
 769/*
 770 * Calling context:
 771 * 1. OS_TXENTRY
 772 * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
 773 *
 774 * If we turn on USE_RXTHREAD, then, no need for critical section.
 775 * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
 776 *
 777 * Must be very very cautious...
 778 *
 779 */
 780struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
 781{
 782        /*
 783         * Please remember to use all the osdep_service api,
 784         * and lock/unlock or _enter/_exit critical to protect
 785         * pfree_xmit_queue
 786         */
 787        unsigned long irqL;
 788        struct xmit_frame *pxframe;
 789        struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
 790
 791        spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
 792        pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
 793                                           struct xmit_frame, list);
 794        if (pxframe) {
 795                list_del_init(&pxframe->list);
 796                pxmitpriv->free_xmitframe_cnt--;
 797                pxframe->buf_addr = NULL;
 798                pxframe->pxmitbuf = NULL;
 799                pxframe->attrib.psta = NULL;
 800                pxframe->pkt = NULL;
 801        }
 802        spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
 803        return pxframe;
 804}
 805
 806void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
 807                          struct xmit_frame *pxmitframe)
 808{
 809        unsigned long irqL;
 810        struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
 811        struct _adapter *padapter = pxmitpriv->adapter;
 812
 813        if (pxmitframe == NULL)
 814                return;
 815        spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
 816        list_del_init(&pxmitframe->list);
 817        if (pxmitframe->pkt)
 818                pxmitframe->pkt = NULL;
 819        list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
 820        pxmitpriv->free_xmitframe_cnt++;
 821        spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
 822        if (netif_queue_stopped(padapter->pnetdev))
 823                netif_wake_queue(padapter->pnetdev);
 824}
 825
 826void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
 827                      struct xmit_frame *pxmitframe)
 828{
 829        if (pxmitframe == NULL)
 830                return;
 831        if (pxmitframe->frame_tag == DATA_FRAMETAG)
 832                r8712_free_xmitframe(pxmitpriv, pxmitframe);
 833}
 834
 835void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
 836                                struct  __queue *pframequeue)
 837{
 838        unsigned long irqL;
 839        struct list_head *plist, *phead;
 840        struct  xmit_frame      *pxmitframe;
 841
 842        spin_lock_irqsave(&(pframequeue->lock), irqL);
 843        phead = &pframequeue->queue;
 844        plist = phead->next;
 845        while (!end_of_queue_search(phead, plist)) {
 846                pxmitframe = container_of(plist, struct xmit_frame, list);
 847                plist = plist->next;
 848                r8712_free_xmitframe(pxmitpriv, pxmitframe);
 849        }
 850        spin_unlock_irqrestore(&(pframequeue->lock), irqL);
 851}
 852
 853static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
 854                                               struct  __queue **ppstapending,
 855                                               struct sta_info *psta, sint up)
 856{
 857
 858        struct tx_servq *ptxservq;
 859        struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
 860
 861        switch (up) {
 862        case 1:
 863        case 2:
 864                ptxservq = &(psta->sta_xmitpriv.bk_q);
 865                *ppstapending = &padapter->xmitpriv.bk_pending;
 866                (phwxmits + 3)->accnt++;
 867                break;
 868        case 4:
 869        case 5:
 870                ptxservq = &(psta->sta_xmitpriv.vi_q);
 871                *ppstapending = &padapter->xmitpriv.vi_pending;
 872                (phwxmits + 1)->accnt++;
 873                break;
 874        case 6:
 875        case 7:
 876                ptxservq = &(psta->sta_xmitpriv.vo_q);
 877                *ppstapending = &padapter->xmitpriv.vo_pending;
 878                (phwxmits + 0)->accnt++;
 879                break;
 880        case 0:
 881        case 3:
 882        default:
 883                ptxservq = &(psta->sta_xmitpriv.be_q);
 884                *ppstapending = &padapter->xmitpriv.be_pending;
 885                (phwxmits + 2)->accnt++;
 886                break;
 887        }
 888        return ptxservq;
 889}
 890
 891/*
 892 * Will enqueue pxmitframe to the proper queue, and indicate it
 893 * to xx_pending list.....
 894 */
 895int r8712_xmit_classifier(struct _adapter *padapter,
 896                          struct xmit_frame *pxmitframe)
 897{
 898        unsigned long irqL0;
 899        struct  __queue *pstapending;
 900        struct sta_info *psta;
 901        struct tx_servq *ptxservq;
 902        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 903        struct sta_priv *pstapriv = &padapter->stapriv;
 904        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 905        bool bmcst = is_multicast_ether_addr(pattrib->ra);
 906
 907        if (pattrib->psta) {
 908                psta = pattrib->psta;
 909        } else {
 910                if (bmcst) {
 911                        psta = r8712_get_bcmc_stainfo(padapter);
 912                } else {
 913                        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 914                                psta = r8712_get_stainfo(pstapriv,
 915                                       get_bssid(pmlmepriv));
 916                        else
 917                                psta = r8712_get_stainfo(pstapriv, pattrib->ra);
 918                }
 919        }
 920        if (psta == NULL)
 921                return -EINVAL;
 922        ptxservq = get_sta_pending(padapter, &pstapending,
 923                   psta, pattrib->priority);
 924        spin_lock_irqsave(&pstapending->lock, irqL0);
 925        if (list_empty(&ptxservq->tx_pending))
 926                list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
 927        list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
 928        ptxservq->qcnt++;
 929        spin_unlock_irqrestore(&pstapending->lock, irqL0);
 930        return 0;
 931}
 932
 933static void alloc_hwxmits(struct _adapter *padapter)
 934{
 935        struct hw_xmit *hwxmits;
 936        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 937
 938        pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
 939        pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry,
 940                                sizeof(struct hw_xmit), GFP_ATOMIC);
 941        if (!pxmitpriv->hwxmits)
 942                return;
 943        hwxmits = pxmitpriv->hwxmits;
 944        if (pxmitpriv->hwxmit_entry == 5) {
 945                pxmitpriv->bmc_txqueue.head = 0;
 946                hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
 947                hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
 948                pxmitpriv->vo_txqueue.head = 0;
 949                hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
 950                hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
 951                pxmitpriv->vi_txqueue.head = 0;
 952                hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
 953                hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
 954                pxmitpriv->bk_txqueue.head = 0;
 955                hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
 956                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
 957                pxmitpriv->be_txqueue.head = 0;
 958                hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
 959                hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
 960        } else if (pxmitpriv->hwxmit_entry == 4) {
 961                pxmitpriv->vo_txqueue.head = 0;
 962                hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
 963                hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
 964                pxmitpriv->vi_txqueue.head = 0;
 965                hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
 966                hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
 967                pxmitpriv->be_txqueue.head = 0;
 968                hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
 969                hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
 970                pxmitpriv->bk_txqueue.head = 0;
 971                hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
 972                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
 973        }
 974}
 975
 976static void free_hwxmits(struct _adapter *padapter)
 977{
 978        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 979
 980        kfree(pxmitpriv->hwxmits);
 981}
 982
 983static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
 984{
 985        sint i;
 986
 987        for (i = 0; i < entry; i++, phwxmit++) {
 988                spin_lock_init(&phwxmit->xmit_lock);
 989                INIT_LIST_HEAD(&phwxmit->pending);
 990                phwxmit->txcmdcnt = 0;
 991                phwxmit->accnt = 0;
 992        }
 993}
 994
 995void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
 996                        struct xmit_buf *pxmitbuf)
 997{
 998        /* pxmitbuf attach to pxmitframe */
 999        pxmitframe->pxmitbuf = pxmitbuf;
1000        /* urb and irp connection */
1001        pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
1002        /* buffer addr assoc */
1003        pxmitframe->buf_addr = pxmitbuf->pbuf;
1004        /* pxmitframe attach to pxmitbuf */
1005        pxmitbuf->priv_data = pxmitframe;
1006}
1007
1008/*
1009 * tx_action == 0 == no frames to transmit
1010 * tx_action > 0 ==> we have frames to transmit
1011 * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
1012 *                                               to transmit 1 frame.
1013 */
1014
1015int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
1016{
1017        unsigned long irqL;
1018        int ret;
1019        struct xmit_buf *pxmitbuf = NULL;
1020        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1021        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1022
1023        r8712_do_queue_select(padapter, pattrib);
1024        spin_lock_irqsave(&pxmitpriv->lock, irqL);
1025        if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1026                ret = false;
1027                r8712_xmit_enqueue(padapter, pxmitframe);
1028                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1029                return ret;
1030        }
1031        pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
1032        if (pxmitbuf == NULL) { /*enqueue packet*/
1033                ret = false;
1034                r8712_xmit_enqueue(padapter, pxmitframe);
1035                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1036        } else { /*dump packet directly*/
1037                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1038                ret = true;
1039                xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
1040                r8712_xmit_direct(padapter, pxmitframe);
1041        }
1042        return ret;
1043}
1044