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 "osdep_intf.h"
  22#include "usb_ops.h"
  23
  24#include <linux/ieee80211.h>
  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 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,
  80                        GFP_ATOMIC);
  81        if (!pxmitpriv->pallocated_frame_buf) {
  82                pxmitpriv->pxmit_frame_buf = NULL;
  83                return -ENOMEM;
  84        }
  85        pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
  86                        ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
  87        pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
  88        for (i = 0; i < NR_XMITFRAME; i++) {
  89                INIT_LIST_HEAD(&(pxframe->list));
  90                pxframe->padapter = padapter;
  91                pxframe->frame_tag = DATA_FRAMETAG;
  92                pxframe->pkt = NULL;
  93                pxframe->buf_addr = NULL;
  94                pxframe->pxmitbuf = NULL;
  95                list_add_tail(&(pxframe->list),
  96                                 &(pxmitpriv->free_xmit_queue.queue));
  97                pxframe++;
  98        }
  99        pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
 100        /*
 101         * init xmit hw_txqueue
 102         */
 103        _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
 104        _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
 105        _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
 106        _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
 107        _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
 108        pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
 109        pxmitpriv->txirp_cnt = 1;
 110        /*per AC pending irp*/
 111        pxmitpriv->beq_cnt = 0;
 112        pxmitpriv->bkq_cnt = 0;
 113        pxmitpriv->viq_cnt = 0;
 114        pxmitpriv->voq_cnt = 0;
 115        /*init xmit_buf*/
 116        _init_queue(&pxmitpriv->free_xmitbuf_queue);
 117        _init_queue(&pxmitpriv->pending_xmitbuf_queue);
 118        pxmitpriv->pallocated_xmitbuf =
 119                kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
 120        if (!pxmitpriv->pallocated_xmitbuf) {
 121                kfree(pxmitpriv->pallocated_frame_buf);
 122                pxmitpriv->pallocated_frame_buf = NULL;
 123                return -ENOMEM;
 124        }
 125        pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
 126                              ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
 127        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 128        for (i = 0; i < NR_XMITBUFF; i++) {
 129                INIT_LIST_HEAD(&pxmitbuf->list);
 130                pxmitbuf->pallocated_buf =
 131                        kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
 132                if (!pxmitbuf->pallocated_buf)
 133                        return -ENOMEM;
 134                pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
 135                                 ((addr_t) (pxmitbuf->pallocated_buf) &
 136                                 (XMITBUF_ALIGN_SZ - 1));
 137                if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
 138                        return -ENOMEM;
 139                list_add_tail(&pxmitbuf->list,
 140                                 &(pxmitpriv->free_xmitbuf_queue.queue));
 141                pxmitbuf++;
 142        }
 143        pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
 144        INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter);
 145        alloc_hwxmits(padapter);
 146        init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 147        tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
 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)
 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)  /* 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 = IEEE80211_FTYPE_DATA;
 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 *psecpriv = &padapter->securitypriv;
 354        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 355        u8 priority[4] = {};
 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) {
 366                        u8 null_key[16] = {};
 367
 368                        pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
 369                        if (bmcst) {
 370                                if (!memcmp(psecpriv->XGrptxmickey
 371                                   [psecpriv->XGrpKeyid].skey,
 372                                   null_key, 16))
 373                                        return -ENOMEM;
 374                                /*start to calculate the mic code*/
 375                                r8712_secmicsetkey(&micdata,
 376                                        psecpriv->XGrptxmickey
 377                                        [psecpriv->XGrpKeyid].skey);
 378                        } else {
 379                                if (!memcmp(&stainfo->tkiptxmickey.skey[0],
 380                                            null_key, 16))
 381                                        return -ENOMEM;
 382                                /* start to calculate the mic code */
 383                                r8712_secmicsetkey(&micdata,
 384                                             &stainfo->tkiptxmickey.skey[0]);
 385                        }
 386                        if (pframe[1] & 1) {   /* ToDS==1 */
 387                                r8712_secmicappend(&micdata,
 388                                                   &pframe[16], 6); /*DA*/
 389                                if (pframe[1] & 2)  /* From Ds==1 */
 390                                        r8712_secmicappend(&micdata,
 391                                                           &pframe[24], 6);
 392                                else
 393                                        r8712_secmicappend(&micdata,
 394                                                           &pframe[10], 6);
 395                        } else {        /* ToDS==0 */
 396                                r8712_secmicappend(&micdata,
 397                                                   &pframe[4], 6); /* DA */
 398                                if (pframe[1] & 2)  /* From Ds==1 */
 399                                        r8712_secmicappend(&micdata,
 400                                                           &pframe[16], 6);
 401                                else
 402                                        r8712_secmicappend(&micdata,
 403                                                           &pframe[10], 6);
 404                        }
 405                        if (pqospriv->qos_option == 1)
 406                                priority[0] = (u8)pxmitframe->attrib.priority;
 407                        r8712_secmicappend(&micdata, &priority[0], 4);
 408                        payload = pframe;
 409                        for (curfragnum = 0; curfragnum < pattrib->nr_frags;
 410                             curfragnum++) {
 411                                payload = (u8 *)RND4((addr_t)(payload));
 412                                payload += pattrib->hdrlen + pattrib->iv_len;
 413                                if ((curfragnum + 1) == pattrib->nr_frags) {
 414                                        length = pattrib->last_txcmdsz -
 415                                                  pattrib->hdrlen -
 416                                                  pattrib->iv_len -
 417                                                  ((psecpriv->sw_encrypt)
 418                                                  ? pattrib->icv_len : 0);
 419                                        r8712_secmicappend(&micdata, payload,
 420                                                           length);
 421                                        payload = payload + length;
 422                                } else {
 423                                        length = pxmitpriv->frag_len -
 424                                            pattrib->hdrlen - pattrib->iv_len -
 425                                            ((psecpriv->sw_encrypt) ?
 426                                            pattrib->icv_len : 0);
 427                                        r8712_secmicappend(&micdata, payload,
 428                                                           length);
 429                                        payload = payload + length +
 430                                                  pattrib->icv_len;
 431                                }
 432                        }
 433                        r8712_secgetmic(&micdata, &(mic[0]));
 434                        /* add mic code  and add the mic code length in
 435                         * last_txcmdsz
 436                         */
 437                        memcpy(payload, &(mic[0]), 8);
 438                        pattrib->last_txcmdsz += 8;
 439                        payload = payload - pattrib->last_txcmdsz + 8;
 440                }
 441        }
 442        return 0;
 443}
 444
 445static sint xmitframe_swencrypt(struct _adapter *padapter,
 446                                struct xmit_frame *pxmitframe)
 447{
 448        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 449
 450        if (pattrib->bswenc) {
 451                switch (pattrib->encrypt) {
 452                case _WEP40_:
 453                case _WEP104_:
 454                        r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
 455                        break;
 456                case _TKIP_:
 457                        r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
 458                        break;
 459                case _AES_:
 460                        r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
 461                        break;
 462                default:
 463                                break;
 464                }
 465        }
 466        return _SUCCESS;
 467}
 468
 469static int make_wlanhdr(struct _adapter *padapter, u8 *hdr,
 470                        struct pkt_attrib *pattrib)
 471{
 472        u16 *qc;
 473
 474        struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
 475        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 476        struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 477        __le16 *fctrl = &pwlanhdr->frame_control;
 478        u8 *bssid;
 479
 480        memset(hdr, 0, WLANHDR_OFFSET);
 481        SetFrameSubType(fctrl, pattrib->subtype);
 482        if (!(pattrib->subtype & IEEE80211_FTYPE_DATA))
 483                return 0;
 484
 485        bssid = get_bssid(pmlmepriv);
 486
 487        if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
 488                /* to_ds = 1, fr_ds = 0; */
 489                SetToDs(fctrl);
 490                ether_addr_copy(pwlanhdr->addr1, bssid);
 491                ether_addr_copy(pwlanhdr->addr2, pattrib->src);
 492                ether_addr_copy(pwlanhdr->addr3, pattrib->dst);
 493        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 494                /* to_ds = 0, fr_ds = 1; */
 495                SetFrDs(fctrl);
 496                ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
 497                ether_addr_copy(pwlanhdr->addr2, bssid);
 498                ether_addr_copy(pwlanhdr->addr3, pattrib->src);
 499        } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 500                   check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 501                ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
 502                ether_addr_copy(pwlanhdr->addr2, pattrib->src);
 503                ether_addr_copy(pwlanhdr->addr3, bssid);
 504        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 505                ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
 506                ether_addr_copy(pwlanhdr->addr2, pattrib->src);
 507                ether_addr_copy(pwlanhdr->addr3, bssid);
 508        } else {
 509                return -EINVAL;
 510        }
 511
 512        if (pattrib->encrypt)
 513                SetPrivacy(fctrl);
 514        if (pqospriv->qos_option) {
 515                qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
 516                if (pattrib->priority)
 517                        SetPriority(qc, pattrib->priority);
 518                SetAckpolicy(qc, pattrib->ack_policy);
 519        }
 520        /* TODO: fill HT Control Field */
 521        /* Update Seq Num will be handled by f/w */
 522        {
 523                struct sta_info *psta;
 524                bool bmcst = is_multicast_ether_addr(pattrib->ra);
 525
 526                if (pattrib->psta)
 527                        psta = pattrib->psta;
 528                else if (bmcst)
 529                        psta = r8712_get_bcmc_stainfo(padapter);
 530                else
 531                        psta = r8712_get_stainfo(&padapter->stapriv,
 532                                                 pattrib->ra);
 533
 534                if (psta) {
 535                        u16 *txtid = psta->sta_xmitpriv.txseq_tid;
 536
 537                        txtid[pattrib->priority]++;
 538                        txtid[pattrib->priority] &= 0xFFF;
 539                        pattrib->seqnum = txtid[pattrib->priority];
 540                        SetSeqNum(hdr, pattrib->seqnum);
 541                }
 542        }
 543
 544        return 0;
 545}
 546
 547static sint r8712_put_snap(u8 *data, u16 h_proto)
 548{
 549        struct ieee80211_snap_hdr *snap;
 550        const u8 *oui;
 551
 552        snap = (struct ieee80211_snap_hdr *)data;
 553        snap->dsap = 0xaa;
 554        snap->ssap = 0xaa;
 555        snap->ctrl = 0x03;
 556        if (h_proto == 0x8137 || h_proto == 0x80f3)
 557                oui = P802_1H_OUI;
 558        else
 559                oui = RFC1042_OUI;
 560        snap->oui[0] = oui[0];
 561        snap->oui[1] = oui[1];
 562        snap->oui[2] = oui[2];
 563        *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
 564        return SNAP_SIZE + sizeof(u16);
 565}
 566
 567/*
 568 * This sub-routine will perform all the following:
 569 * 1. remove 802.3 header.
 570 * 2. create wlan_header, based on the info in pxmitframe
 571 * 3. append sta's iv/ext-iv
 572 * 4. append LLC
 573 * 5. move frag chunk from pframe to pxmitframe->mem
 574 * 6. apply sw-encrypt, if necessary.
 575 */
 576sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
 577                        struct xmit_frame *pxmitframe)
 578{
 579        struct pkt_file pktfile;
 580
 581        sint    frg_len, mpdu_len, llc_sz;
 582        u32     mem_sz;
 583        u8      frg_inx;
 584        addr_t addr;
 585        u8 *pframe, *mem_start, *ptxdesc;
 586        struct sta_info         *psta;
 587        struct security_priv    *psecpriv = &padapter->securitypriv;
 588        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 589        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
 590        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 591        u8 *pbuf_start;
 592        bool bmcst = is_multicast_ether_addr(pattrib->ra);
 593
 594        if (!pattrib->psta)
 595                return _FAIL;
 596        psta = pattrib->psta;
 597        if (!pxmitframe->buf_addr)
 598                return _FAIL;
 599        pbuf_start = pxmitframe->buf_addr;
 600        ptxdesc = pbuf_start;
 601        mem_start = pbuf_start + TXDESC_OFFSET;
 602        if (make_wlanhdr(padapter, mem_start, pattrib))
 603                return _FAIL;
 604        _r8712_open_pktfile(pkt, &pktfile);
 605        _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
 606        if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 607                /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
 608                if (pattrib->ether_type == 0x8712) {
 609                        /* take care -  update_txdesc overwrite this */
 610                        _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
 611                }
 612        }
 613        pattrib->pktlen = pktfile.pkt_len;
 614        frg_inx = 0;
 615        frg_len = pxmitpriv->frag_len - 4;
 616        while (1) {
 617                llc_sz = 0;
 618                mpdu_len = frg_len;
 619                pframe = mem_start;
 620                SetMFrag(mem_start);
 621                pframe += pattrib->hdrlen;
 622                mpdu_len -= pattrib->hdrlen;
 623                /* adding icv, if necessary...*/
 624                if (pattrib->iv_len) {
 625                        if (psta) {
 626                                switch (pattrib->encrypt) {
 627                                case _WEP40_:
 628                                case _WEP104_:
 629                                        WEP_IV(pattrib->iv, psta->txpn,
 630                                               (u8)psecpriv->PrivacyKeyIndex);
 631                                        break;
 632                                case _TKIP_:
 633                                        if (bmcst)
 634                                                TKIP_IV(pattrib->iv,
 635                                                    psta->txpn,
 636                                                    (u8)psecpriv->XGrpKeyid);
 637                                        else
 638                                                TKIP_IV(pattrib->iv, psta->txpn,
 639                                                        0);
 640                                        break;
 641                                case _AES_:
 642                                        if (bmcst)
 643                                                AES_IV(pattrib->iv, psta->txpn,
 644                                                    (u8)psecpriv->XGrpKeyid);
 645                                        else
 646                                                AES_IV(pattrib->iv, psta->txpn,
 647                                                       0);
 648                                        break;
 649                                }
 650                        }
 651                        memcpy(pframe, pattrib->iv, pattrib->iv_len);
 652                        pframe += pattrib->iv_len;
 653                        mpdu_len -= pattrib->iv_len;
 654                }
 655                if (frg_inx == 0) {
 656                        llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
 657                        pframe += llc_sz;
 658                        mpdu_len -= llc_sz;
 659                }
 660                if ((pattrib->icv_len > 0) && (pattrib->bswenc))
 661                        mpdu_len -= pattrib->icv_len;
 662                if (bmcst)
 663                        mem_sz = _r8712_pktfile_read(&pktfile, pframe,
 664                                 pattrib->pktlen);
 665                else
 666                        mem_sz = _r8712_pktfile_read(&pktfile, pframe,
 667                                 mpdu_len);
 668                pframe += mem_sz;
 669                if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
 670                        memcpy(pframe, pattrib->icv, pattrib->icv_len);
 671                        pframe += pattrib->icv_len;
 672                }
 673                frg_inx++;
 674                if (bmcst || r8712_endofpktfile(&pktfile)) {
 675                        pattrib->nr_frags = frg_inx;
 676                        pattrib->last_txcmdsz = pattrib->hdrlen +
 677                                                pattrib->iv_len +
 678                                                ((pattrib->nr_frags == 1) ?
 679                                                llc_sz : 0) +
 680                                                ((pattrib->bswenc) ?
 681                                                pattrib->icv_len : 0) + mem_sz;
 682                        ClearMFrag(mem_start);
 683                        break;
 684                }
 685                addr = (addr_t)(pframe);
 686                mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
 687                memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
 688        }
 689
 690        if (xmitframe_addmic(padapter, pxmitframe))
 691                return _FAIL;
 692        xmitframe_swencrypt(padapter, pxmitframe);
 693        return _SUCCESS;
 694}
 695
 696void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
 697{
 698        uint    protection;
 699        u8      *perp;
 700        uint    erp_len;
 701        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 702        struct  registry_priv *pregistrypriv = &padapter->registrypriv;
 703
 704        switch (pxmitpriv->vcs_setting) {
 705        case DISABLE_VCS:
 706                pxmitpriv->vcs = NONE_VCS;
 707                break;
 708        case ENABLE_VCS:
 709                break;
 710        case AUTO_VCS:
 711        default:
 712                perp = r8712_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len);
 713                if (!perp) {
 714                        pxmitpriv->vcs = NONE_VCS;
 715                } else {
 716                        protection = (*(perp + 2)) & BIT(1);
 717                        if (protection) {
 718                                if (pregistrypriv->vcs_type == RTS_CTS)
 719                                        pxmitpriv->vcs = RTS_CTS;
 720                                else
 721                                        pxmitpriv->vcs = CTS_TO_SELF;
 722                        } else {
 723                                pxmitpriv->vcs = NONE_VCS;
 724                        }
 725                }
 726                break;
 727        }
 728}
 729
 730struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
 731{
 732        unsigned long irqL;
 733        struct xmit_buf *pxmitbuf;
 734        struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 735
 736        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
 737        pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
 738                                            struct xmit_buf, list);
 739        if (pxmitbuf) {
 740                list_del_init(&pxmitbuf->list);
 741                pxmitpriv->free_xmitbuf_cnt--;
 742        }
 743        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
 744        return pxmitbuf;
 745}
 746
 747void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
 748{
 749        unsigned long irqL;
 750        struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 751
 752        if (!pxmitbuf)
 753                return;
 754        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
 755        list_del_init(&pxmitbuf->list);
 756        list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
 757        pxmitpriv->free_xmitbuf_cnt++;
 758        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
 759}
 760
 761/*
 762 * Calling context:
 763 * 1. OS_TXENTRY
 764 * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
 765 *
 766 * If we turn on USE_RXTHREAD, then, no need for critical section.
 767 * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
 768 *
 769 * Must be very very cautious...
 770 *
 771 */
 772struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
 773{
 774        /*
 775         * Please remember to use all the osdep_service api,
 776         * and lock/unlock or _enter/_exit critical to protect
 777         * pfree_xmit_queue
 778         */
 779        unsigned long irqL;
 780        struct xmit_frame *pxframe;
 781        struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
 782
 783        spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
 784        pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
 785                                           struct xmit_frame, list);
 786        if (pxframe) {
 787                list_del_init(&pxframe->list);
 788                pxmitpriv->free_xmitframe_cnt--;
 789                pxframe->buf_addr = NULL;
 790                pxframe->pxmitbuf = NULL;
 791                pxframe->attrib.psta = NULL;
 792                pxframe->pkt = NULL;
 793        }
 794        spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
 795        return pxframe;
 796}
 797
 798void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
 799                          struct xmit_frame *pxmitframe)
 800{
 801        unsigned long irqL;
 802        struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
 803        struct _adapter *padapter = pxmitpriv->adapter;
 804
 805        if (!pxmitframe)
 806                return;
 807        spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
 808        list_del_init(&pxmitframe->list);
 809        if (pxmitframe->pkt)
 810                pxmitframe->pkt = NULL;
 811        list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
 812        pxmitpriv->free_xmitframe_cnt++;
 813        spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
 814        if (netif_queue_stopped(padapter->pnetdev))
 815                netif_wake_queue(padapter->pnetdev);
 816}
 817
 818void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
 819                      struct xmit_frame *pxmitframe)
 820{
 821        if (!pxmitframe)
 822                return;
 823        if (pxmitframe->frame_tag == DATA_FRAMETAG)
 824                r8712_free_xmitframe(pxmitpriv, pxmitframe);
 825}
 826
 827void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
 828                                struct  __queue *pframequeue)
 829{
 830        unsigned long irqL;
 831        struct list_head *plist, *phead;
 832        struct  xmit_frame      *pxmitframe;
 833
 834        spin_lock_irqsave(&(pframequeue->lock), irqL);
 835        phead = &pframequeue->queue;
 836        plist = phead->next;
 837        while (!end_of_queue_search(phead, plist)) {
 838                pxmitframe = container_of(plist, struct xmit_frame, list);
 839                plist = plist->next;
 840                r8712_free_xmitframe(pxmitpriv, pxmitframe);
 841        }
 842        spin_unlock_irqrestore(&(pframequeue->lock), irqL);
 843}
 844
 845static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
 846                                               struct  __queue **ppstapending,
 847                                               struct sta_info *psta, sint up)
 848{
 849        struct tx_servq *ptxservq;
 850        struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
 851
 852        switch (up) {
 853        case 1:
 854        case 2:
 855                ptxservq = &(psta->sta_xmitpriv.bk_q);
 856                *ppstapending = &padapter->xmitpriv.bk_pending;
 857                (phwxmits + 3)->accnt++;
 858                break;
 859        case 4:
 860        case 5:
 861                ptxservq = &(psta->sta_xmitpriv.vi_q);
 862                *ppstapending = &padapter->xmitpriv.vi_pending;
 863                (phwxmits + 1)->accnt++;
 864                break;
 865        case 6:
 866        case 7:
 867                ptxservq = &(psta->sta_xmitpriv.vo_q);
 868                *ppstapending = &padapter->xmitpriv.vo_pending;
 869                (phwxmits + 0)->accnt++;
 870                break;
 871        case 0:
 872        case 3:
 873        default:
 874                ptxservq = &(psta->sta_xmitpriv.be_q);
 875                *ppstapending = &padapter->xmitpriv.be_pending;
 876                (phwxmits + 2)->accnt++;
 877                break;
 878        }
 879        return ptxservq;
 880}
 881
 882/*
 883 * Will enqueue pxmitframe to the proper queue, and indicate it
 884 * to xx_pending list.....
 885 */
 886int r8712_xmit_classifier(struct _adapter *padapter,
 887                          struct xmit_frame *pxmitframe)
 888{
 889        unsigned long irqL0;
 890        struct  __queue *pstapending;
 891        struct sta_info *psta;
 892        struct tx_servq *ptxservq;
 893        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 894        struct sta_priv *pstapriv = &padapter->stapriv;
 895        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 896        bool bmcst = is_multicast_ether_addr(pattrib->ra);
 897
 898        if (pattrib->psta) {
 899                psta = pattrib->psta;
 900        } else {
 901                if (bmcst) {
 902                        psta = r8712_get_bcmc_stainfo(padapter);
 903                } else {
 904                        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 905                                psta = r8712_get_stainfo(pstapriv,
 906                                       get_bssid(pmlmepriv));
 907                        else
 908                                psta = r8712_get_stainfo(pstapriv, pattrib->ra);
 909                }
 910        }
 911        if (!psta)
 912                return -EINVAL;
 913        ptxservq = get_sta_pending(padapter, &pstapending,
 914                   psta, pattrib->priority);
 915        spin_lock_irqsave(&pstapending->lock, irqL0);
 916        if (list_empty(&ptxservq->tx_pending))
 917                list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
 918        list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
 919        ptxservq->qcnt++;
 920        spin_unlock_irqrestore(&pstapending->lock, irqL0);
 921        return 0;
 922}
 923
 924static void alloc_hwxmits(struct _adapter *padapter)
 925{
 926        struct hw_xmit *hwxmits;
 927        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 928
 929        pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
 930        pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry,
 931                                sizeof(struct hw_xmit), GFP_ATOMIC);
 932        if (!pxmitpriv->hwxmits)
 933                return;
 934        hwxmits = pxmitpriv->hwxmits;
 935        if (pxmitpriv->hwxmit_entry == 5) {
 936                pxmitpriv->bmc_txqueue.head = 0;
 937                hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
 938                hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
 939                pxmitpriv->vo_txqueue.head = 0;
 940                hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
 941                hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
 942                pxmitpriv->vi_txqueue.head = 0;
 943                hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
 944                hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
 945                pxmitpriv->bk_txqueue.head = 0;
 946                hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
 947                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
 948                pxmitpriv->be_txqueue.head = 0;
 949                hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
 950                hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
 951        } else if (pxmitpriv->hwxmit_entry == 4) {
 952                pxmitpriv->vo_txqueue.head = 0;
 953                hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
 954                hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
 955                pxmitpriv->vi_txqueue.head = 0;
 956                hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
 957                hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
 958                pxmitpriv->be_txqueue.head = 0;
 959                hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
 960                hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
 961                pxmitpriv->bk_txqueue.head = 0;
 962                hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
 963                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
 964        }
 965}
 966
 967static void free_hwxmits(struct _adapter *padapter)
 968{
 969        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 970
 971        kfree(pxmitpriv->hwxmits);
 972}
 973
 974static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
 975{
 976        sint i;
 977
 978        for (i = 0; i < entry; i++, phwxmit++) {
 979                spin_lock_init(&phwxmit->xmit_lock);
 980                INIT_LIST_HEAD(&phwxmit->pending);
 981                phwxmit->txcmdcnt = 0;
 982                phwxmit->accnt = 0;
 983        }
 984}
 985
 986void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
 987                        struct xmit_buf *pxmitbuf)
 988{
 989        /* pxmitbuf attach to pxmitframe */
 990        pxmitframe->pxmitbuf = pxmitbuf;
 991        /* urb and irp connection */
 992        pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
 993        /* buffer addr assoc */
 994        pxmitframe->buf_addr = pxmitbuf->pbuf;
 995        /* pxmitframe attach to pxmitbuf */
 996        pxmitbuf->priv_data = pxmitframe;
 997}
 998
 999/*
1000 * tx_action == 0 == no frames to transmit
1001 * tx_action > 0 ==> we have frames to transmit
1002 * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
1003 *                                               to transmit 1 frame.
1004 */
1005
1006int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
1007{
1008        unsigned long irqL;
1009        int ret;
1010        struct xmit_buf *pxmitbuf = NULL;
1011        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1012        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1013
1014        r8712_do_queue_select(padapter, pattrib);
1015        spin_lock_irqsave(&pxmitpriv->lock, irqL);
1016        if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1017                ret = false;
1018                r8712_xmit_enqueue(padapter, pxmitframe);
1019                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1020                return ret;
1021        }
1022        pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
1023        if (!pxmitbuf) { /*enqueue packet*/
1024                ret = false;
1025                r8712_xmit_enqueue(padapter, pxmitframe);
1026                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1027        } else { /*dump packet directly*/
1028                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1029                ret = true;
1030                xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
1031                r8712_xmit_direct(padapter, pxmitframe);
1032        }
1033        return ret;
1034}
1035