linux/drivers/net/wireless/b43/xmit.c
<<
>>
Prefs
   1/*
   2
   3  Broadcom B43 wireless driver
   4
   5  Transmission (TX/RX) related functions.
   6
   7  Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
   8  Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it>
   9  Copyright (C) 2005, 2006 Michael Buesch <mb@bu3sch.de>
  10  Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
  11  Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
  12
  13  This program is free software; you can redistribute it and/or modify
  14  it under the terms of the GNU General Public License as published by
  15  the Free Software Foundation; either version 2 of the License, or
  16  (at your option) any later version.
  17
  18  This program is distributed in the hope that it will be useful,
  19  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21  GNU General Public License for more details.
  22
  23  You should have received a copy of the GNU General Public License
  24  along with this program; see the file COPYING.  If not, write to
  25  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  26  Boston, MA 02110-1301, USA.
  27
  28*/
  29
  30#include "b43.h"
  31#include "phy_common.h"
  32#include "dma.h"
  33#include "pio.h"
  34
  35
  36/* Extract the bitrate index out of a CCK PLCP header. */
  37static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
  38{
  39        switch (plcp->raw[0]) {
  40        case 0x0A:
  41                return 0;
  42        case 0x14:
  43                return 1;
  44        case 0x37:
  45                return 2;
  46        case 0x6E:
  47                return 3;
  48        }
  49        return -1;
  50}
  51
  52/* Extract the bitrate index out of an OFDM PLCP header. */
  53static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
  54{
  55        int base = aphy ? 0 : 4;
  56
  57        switch (plcp->raw[0] & 0xF) {
  58        case 0xB:
  59                return base + 0;
  60        case 0xF:
  61                return base + 1;
  62        case 0xA:
  63                return base + 2;
  64        case 0xE:
  65                return base + 3;
  66        case 0x9:
  67                return base + 4;
  68        case 0xD:
  69                return base + 5;
  70        case 0x8:
  71                return base + 6;
  72        case 0xC:
  73                return base + 7;
  74        }
  75        return -1;
  76}
  77
  78u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
  79{
  80        switch (bitrate) {
  81        case B43_CCK_RATE_1MB:
  82                return 0x0A;
  83        case B43_CCK_RATE_2MB:
  84                return 0x14;
  85        case B43_CCK_RATE_5MB:
  86                return 0x37;
  87        case B43_CCK_RATE_11MB:
  88                return 0x6E;
  89        }
  90        B43_WARN_ON(1);
  91        return 0;
  92}
  93
  94u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate)
  95{
  96        switch (bitrate) {
  97        case B43_OFDM_RATE_6MB:
  98                return 0xB;
  99        case B43_OFDM_RATE_9MB:
 100                return 0xF;
 101        case B43_OFDM_RATE_12MB:
 102                return 0xA;
 103        case B43_OFDM_RATE_18MB:
 104                return 0xE;
 105        case B43_OFDM_RATE_24MB:
 106                return 0x9;
 107        case B43_OFDM_RATE_36MB:
 108                return 0xD;
 109        case B43_OFDM_RATE_48MB:
 110                return 0x8;
 111        case B43_OFDM_RATE_54MB:
 112                return 0xC;
 113        }
 114        B43_WARN_ON(1);
 115        return 0;
 116}
 117
 118void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
 119                           const u16 octets, const u8 bitrate)
 120{
 121        __u8 *raw = plcp->raw;
 122
 123        if (b43_is_ofdm_rate(bitrate)) {
 124                u32 d;
 125
 126                d = b43_plcp_get_ratecode_ofdm(bitrate);
 127                B43_WARN_ON(octets & 0xF000);
 128                d |= (octets << 5);
 129                plcp->data = cpu_to_le32(d);
 130        } else {
 131                u32 plen;
 132
 133                plen = octets * 16 / bitrate;
 134                if ((octets * 16 % bitrate) > 0) {
 135                        plen++;
 136                        if ((bitrate == B43_CCK_RATE_11MB)
 137                            && ((octets * 8 % 11) < 4)) {
 138                                raw[1] = 0x84;
 139                        } else
 140                                raw[1] = 0x04;
 141                } else
 142                        raw[1] = 0x04;
 143                plcp->data |= cpu_to_le32(plen << 16);
 144                raw[0] = b43_plcp_get_ratecode_cck(bitrate);
 145        }
 146}
 147
 148static u8 b43_calc_fallback_rate(u8 bitrate)
 149{
 150        switch (bitrate) {
 151        case B43_CCK_RATE_1MB:
 152                return B43_CCK_RATE_1MB;
 153        case B43_CCK_RATE_2MB:
 154                return B43_CCK_RATE_1MB;
 155        case B43_CCK_RATE_5MB:
 156                return B43_CCK_RATE_2MB;
 157        case B43_CCK_RATE_11MB:
 158                return B43_CCK_RATE_5MB;
 159        case B43_OFDM_RATE_6MB:
 160                return B43_CCK_RATE_5MB;
 161        case B43_OFDM_RATE_9MB:
 162                return B43_OFDM_RATE_6MB;
 163        case B43_OFDM_RATE_12MB:
 164                return B43_OFDM_RATE_9MB;
 165        case B43_OFDM_RATE_18MB:
 166                return B43_OFDM_RATE_12MB;
 167        case B43_OFDM_RATE_24MB:
 168                return B43_OFDM_RATE_18MB;
 169        case B43_OFDM_RATE_36MB:
 170                return B43_OFDM_RATE_24MB;
 171        case B43_OFDM_RATE_48MB:
 172                return B43_OFDM_RATE_36MB;
 173        case B43_OFDM_RATE_54MB:
 174                return B43_OFDM_RATE_48MB;
 175        }
 176        B43_WARN_ON(1);
 177        return 0;
 178}
 179
 180/* Generate a TX data header. */
 181int b43_generate_txhdr(struct b43_wldev *dev,
 182                       u8 *_txhdr,
 183                       struct sk_buff *skb_frag,
 184                       struct ieee80211_tx_info *info,
 185                       u16 cookie)
 186{
 187        const unsigned char *fragment_data = skb_frag->data;
 188        unsigned int fragment_len = skb_frag->len;
 189        struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
 190        const struct b43_phy *phy = &dev->phy;
 191        const struct ieee80211_hdr *wlhdr =
 192            (const struct ieee80211_hdr *)fragment_data;
 193        int use_encryption = !!info->control.hw_key;
 194        __le16 fctl = wlhdr->frame_control;
 195        struct ieee80211_rate *fbrate;
 196        u8 rate, rate_fb;
 197        int rate_ofdm, rate_fb_ofdm;
 198        unsigned int plcp_fragment_len;
 199        u32 mac_ctl = 0;
 200        u16 phy_ctl = 0;
 201        u8 extra_ft = 0;
 202        struct ieee80211_rate *txrate;
 203        struct ieee80211_tx_rate *rates;
 204
 205        memset(txhdr, 0, sizeof(*txhdr));
 206
 207        txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
 208        rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
 209        rate_ofdm = b43_is_ofdm_rate(rate);
 210        fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : txrate;
 211        rate_fb = fbrate->hw_value;
 212        rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
 213
 214        if (rate_ofdm)
 215                txhdr->phy_rate = b43_plcp_get_ratecode_ofdm(rate);
 216        else
 217                txhdr->phy_rate = b43_plcp_get_ratecode_cck(rate);
 218        txhdr->mac_frame_ctl = wlhdr->frame_control;
 219        memcpy(txhdr->tx_receiver, wlhdr->addr1, 6);
 220
 221        /* Calculate duration for fallback rate */
 222        if ((rate_fb == rate) ||
 223            (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
 224            (wlhdr->duration_id == cpu_to_le16(0))) {
 225                /* If the fallback rate equals the normal rate or the
 226                 * dur_id field contains an AID, CFP magic or 0,
 227                 * use the original dur_id field. */
 228                txhdr->dur_fb = wlhdr->duration_id;
 229        } else {
 230                txhdr->dur_fb = ieee80211_generic_frame_duration(
 231                        dev->wl->hw, info->control.vif, fragment_len, fbrate);
 232        }
 233
 234        plcp_fragment_len = fragment_len + FCS_LEN;
 235        if (use_encryption) {
 236                u8 key_idx = info->control.hw_key->hw_key_idx;
 237                struct b43_key *key;
 238                int wlhdr_len;
 239                size_t iv_len;
 240
 241                B43_WARN_ON(key_idx >= ARRAY_SIZE(dev->key));
 242                key = &(dev->key[key_idx]);
 243
 244                if (unlikely(!key->keyconf)) {
 245                        /* This key is invalid. This might only happen
 246                         * in a short timeframe after machine resume before
 247                         * we were able to reconfigure keys.
 248                         * Drop this packet completely. Do not transmit it
 249                         * unencrypted to avoid leaking information. */
 250                        return -ENOKEY;
 251                }
 252
 253                /* Hardware appends ICV. */
 254                plcp_fragment_len += info->control.hw_key->icv_len;
 255
 256                key_idx = b43_kidx_to_fw(dev, key_idx);
 257                mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
 258                           B43_TXH_MAC_KEYIDX;
 259                mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
 260                           B43_TXH_MAC_KEYALG;
 261                wlhdr_len = ieee80211_hdrlen(fctl);
 262                if (key->algorithm == B43_SEC_ALGO_TKIP) {
 263                        u16 phase1key[5];
 264                        int i;
 265                        /* we give the phase1key and iv16 here, the key is stored in
 266                         * shm. With that the hardware can do phase 2 and encryption.
 267                         */
 268                        ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
 269                                        IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
 270                        /* phase1key is in host endian. Copy to little-endian txhdr->iv. */
 271                        for (i = 0; i < 5; i++) {
 272                                txhdr->iv[i * 2 + 0] = phase1key[i];
 273                                txhdr->iv[i * 2 + 1] = phase1key[i] >> 8;
 274                        }
 275                        /* iv16 */
 276                        memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3);
 277                } else {
 278                        iv_len = min((size_t) info->control.hw_key->iv_len,
 279                                     ARRAY_SIZE(txhdr->iv));
 280                        memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
 281                }
 282        }
 283        if (b43_is_old_txhdr_format(dev)) {
 284                b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
 285                                      plcp_fragment_len, rate);
 286        } else {
 287                b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->new_format.plcp),
 288                                      plcp_fragment_len, rate);
 289        }
 290        b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
 291                              plcp_fragment_len, rate_fb);
 292
 293        /* Extra Frame Types */
 294        if (rate_fb_ofdm)
 295                extra_ft |= B43_TXH_EFT_FB_OFDM;
 296        else
 297                extra_ft |= B43_TXH_EFT_FB_CCK;
 298
 299        /* Set channel radio code. Note that the micrcode ORs 0x100 to
 300         * this value before comparing it to the value in SHM, if this
 301         * is a 5Ghz packet.
 302         */
 303        txhdr->chan_radio_code = phy->channel;
 304
 305        /* PHY TX Control word */
 306        if (rate_ofdm)
 307                phy_ctl |= B43_TXH_PHY_ENC_OFDM;
 308        else
 309                phy_ctl |= B43_TXH_PHY_ENC_CCK;
 310        if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
 311                phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
 312
 313        switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
 314        case 0: /* Default */
 315                phy_ctl |= B43_TXH_PHY_ANT01AUTO;
 316                break;
 317        case 1: /* Antenna 0 */
 318                phy_ctl |= B43_TXH_PHY_ANT0;
 319                break;
 320        case 2: /* Antenna 1 */
 321                phy_ctl |= B43_TXH_PHY_ANT1;
 322                break;
 323        case 3: /* Antenna 2 */
 324                phy_ctl |= B43_TXH_PHY_ANT2;
 325                break;
 326        case 4: /* Antenna 3 */
 327                phy_ctl |= B43_TXH_PHY_ANT3;
 328                break;
 329        default:
 330                B43_WARN_ON(1);
 331        }
 332
 333        rates = info->control.rates;
 334        /* MAC control */
 335        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
 336                mac_ctl |= B43_TXH_MAC_ACK;
 337        /* use hardware sequence counter as the non-TID counter */
 338        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
 339                mac_ctl |= B43_TXH_MAC_HWSEQ;
 340        if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
 341                mac_ctl |= B43_TXH_MAC_STMSDU;
 342        if (phy->type == B43_PHYTYPE_A)
 343                mac_ctl |= B43_TXH_MAC_5GHZ;
 344
 345        /* Overwrite rates[0].count to make the retry calculation
 346         * in the tx status easier. need the actual retry limit to
 347         * detect whether the fallback rate was used.
 348         */
 349        if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
 350            (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
 351                rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
 352                mac_ctl |= B43_TXH_MAC_LONGFRAME;
 353        } else {
 354                rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
 355        }
 356
 357        /* Generate the RTS or CTS-to-self frame */
 358        if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
 359            (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
 360                unsigned int len;
 361                struct ieee80211_hdr *hdr;
 362                int rts_rate, rts_rate_fb;
 363                int rts_rate_ofdm, rts_rate_fb_ofdm;
 364                struct b43_plcp_hdr6 *plcp;
 365                struct ieee80211_rate *rts_cts_rate;
 366
 367                rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
 368
 369                rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
 370                rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
 371                rts_rate_fb = b43_calc_fallback_rate(rts_rate);
 372                rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
 373
 374                if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
 375                        struct ieee80211_cts *cts;
 376
 377                        if (b43_is_old_txhdr_format(dev)) {
 378                                cts = (struct ieee80211_cts *)
 379                                        (txhdr->old_format.rts_frame);
 380                        } else {
 381                                cts = (struct ieee80211_cts *)
 382                                        (txhdr->new_format.rts_frame);
 383                        }
 384                        ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
 385                                                fragment_data, fragment_len,
 386                                                info, cts);
 387                        mac_ctl |= B43_TXH_MAC_SENDCTS;
 388                        len = sizeof(struct ieee80211_cts);
 389                } else {
 390                        struct ieee80211_rts *rts;
 391
 392                        if (b43_is_old_txhdr_format(dev)) {
 393                                rts = (struct ieee80211_rts *)
 394                                        (txhdr->old_format.rts_frame);
 395                        } else {
 396                                rts = (struct ieee80211_rts *)
 397                                        (txhdr->new_format.rts_frame);
 398                        }
 399                        ieee80211_rts_get(dev->wl->hw, info->control.vif,
 400                                          fragment_data, fragment_len,
 401                                          info, rts);
 402                        mac_ctl |= B43_TXH_MAC_SENDRTS;
 403                        len = sizeof(struct ieee80211_rts);
 404                }
 405                len += FCS_LEN;
 406
 407                /* Generate the PLCP headers for the RTS/CTS frame */
 408                if (b43_is_old_txhdr_format(dev))
 409                        plcp = &txhdr->old_format.rts_plcp;
 410                else
 411                        plcp = &txhdr->new_format.rts_plcp;
 412                b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
 413                                      len, rts_rate);
 414                plcp = &txhdr->rts_plcp_fb;
 415                b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
 416                                      len, rts_rate_fb);
 417
 418                if (b43_is_old_txhdr_format(dev)) {
 419                        hdr = (struct ieee80211_hdr *)
 420                                (&txhdr->old_format.rts_frame);
 421                } else {
 422                        hdr = (struct ieee80211_hdr *)
 423                                (&txhdr->new_format.rts_frame);
 424                }
 425                txhdr->rts_dur_fb = hdr->duration_id;
 426
 427                if (rts_rate_ofdm) {
 428                        extra_ft |= B43_TXH_EFT_RTS_OFDM;
 429                        txhdr->phy_rate_rts =
 430                            b43_plcp_get_ratecode_ofdm(rts_rate);
 431                } else {
 432                        extra_ft |= B43_TXH_EFT_RTS_CCK;
 433                        txhdr->phy_rate_rts =
 434                            b43_plcp_get_ratecode_cck(rts_rate);
 435                }
 436                if (rts_rate_fb_ofdm)
 437                        extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
 438                else
 439                        extra_ft |= B43_TXH_EFT_RTSFB_CCK;
 440        }
 441
 442        /* Magic cookie */
 443        if (b43_is_old_txhdr_format(dev))
 444                txhdr->old_format.cookie = cpu_to_le16(cookie);
 445        else
 446                txhdr->new_format.cookie = cpu_to_le16(cookie);
 447
 448        /* Apply the bitfields */
 449        txhdr->mac_ctl = cpu_to_le32(mac_ctl);
 450        txhdr->phy_ctl = cpu_to_le16(phy_ctl);
 451        txhdr->extra_ft = extra_ft;
 452
 453        return 0;
 454}
 455
 456static s8 b43_rssi_postprocess(struct b43_wldev *dev,
 457                               u8 in_rssi, int ofdm,
 458                               int adjust_2053, int adjust_2050)
 459{
 460        struct b43_phy *phy = &dev->phy;
 461        struct b43_phy_g *gphy = phy->g;
 462        s32 tmp;
 463
 464        switch (phy->radio_ver) {
 465        case 0x2050:
 466                if (ofdm) {
 467                        tmp = in_rssi;
 468                        if (tmp > 127)
 469                                tmp -= 256;
 470                        tmp *= 73;
 471                        tmp /= 64;
 472                        if (adjust_2050)
 473                                tmp += 25;
 474                        else
 475                                tmp -= 3;
 476                } else {
 477                        if (dev->dev->bus->sprom.
 478                            boardflags_lo & B43_BFL_RSSI) {
 479                                if (in_rssi > 63)
 480                                        in_rssi = 63;
 481                                B43_WARN_ON(phy->type != B43_PHYTYPE_G);
 482                                tmp = gphy->nrssi_lt[in_rssi];
 483                                tmp = 31 - tmp;
 484                                tmp *= -131;
 485                                tmp /= 128;
 486                                tmp -= 57;
 487                        } else {
 488                                tmp = in_rssi;
 489                                tmp = 31 - tmp;
 490                                tmp *= -149;
 491                                tmp /= 128;
 492                                tmp -= 68;
 493                        }
 494                        if (phy->type == B43_PHYTYPE_G && adjust_2050)
 495                                tmp += 25;
 496                }
 497                break;
 498        case 0x2060:
 499                if (in_rssi > 127)
 500                        tmp = in_rssi - 256;
 501                else
 502                        tmp = in_rssi;
 503                break;
 504        default:
 505                tmp = in_rssi;
 506                tmp -= 11;
 507                tmp *= 103;
 508                tmp /= 64;
 509                if (adjust_2053)
 510                        tmp -= 109;
 511                else
 512                        tmp -= 83;
 513        }
 514
 515        return (s8) tmp;
 516}
 517
 518//TODO
 519#if 0
 520static s8 b43_rssinoise_postprocess(struct b43_wldev *dev, u8 in_rssi)
 521{
 522        struct b43_phy *phy = &dev->phy;
 523        s8 ret;
 524
 525        if (phy->type == B43_PHYTYPE_A) {
 526                //TODO: Incomplete specs.
 527                ret = 0;
 528        } else
 529                ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1);
 530
 531        return ret;
 532}
 533#endif
 534
 535void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 536{
 537        struct ieee80211_rx_status status;
 538        struct b43_plcp_hdr6 *plcp;
 539        struct ieee80211_hdr *wlhdr;
 540        const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
 541        __le16 fctl;
 542        u16 phystat0, phystat3, chanstat, mactime;
 543        u32 macstat;
 544        u16 chanid;
 545        u16 phytype;
 546        int padding;
 547
 548        memset(&status, 0, sizeof(status));
 549
 550        /* Get metadata about the frame from the header. */
 551        phystat0 = le16_to_cpu(rxhdr->phy_status0);
 552        phystat3 = le16_to_cpu(rxhdr->phy_status3);
 553        macstat = le32_to_cpu(rxhdr->mac_status);
 554        mactime = le16_to_cpu(rxhdr->mac_time);
 555        chanstat = le16_to_cpu(rxhdr->channel);
 556        phytype = chanstat & B43_RX_CHAN_PHYTYPE;
 557
 558        if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
 559                dev->wl->ieee_stats.dot11FCSErrorCount++;
 560                status.flag |= RX_FLAG_FAILED_FCS_CRC;
 561        }
 562        if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
 563                status.flag |= RX_FLAG_FAILED_PLCP_CRC;
 564        if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
 565                status.flag |= RX_FLAG_SHORTPRE;
 566        if (macstat & B43_RX_MAC_DECERR) {
 567                /* Decryption with the given key failed.
 568                 * Drop the packet. We also won't be able to decrypt it with
 569                 * the key in software. */
 570                goto drop;
 571        }
 572
 573        /* Skip PLCP and padding */
 574        padding = (macstat & B43_RX_MAC_PADDING) ? 2 : 0;
 575        if (unlikely(skb->len < (sizeof(struct b43_plcp_hdr6) + padding))) {
 576                b43dbg(dev->wl, "RX: Packet size underrun (1)\n");
 577                goto drop;
 578        }
 579        plcp = (struct b43_plcp_hdr6 *)(skb->data + padding);
 580        skb_pull(skb, sizeof(struct b43_plcp_hdr6) + padding);
 581        /* The skb contains the Wireless Header + payload data now */
 582        if (unlikely(skb->len < (2 + 2 + 6 /*minimum hdr */  + FCS_LEN))) {
 583                b43dbg(dev->wl, "RX: Packet size underrun (2)\n");
 584                goto drop;
 585        }
 586        wlhdr = (struct ieee80211_hdr *)(skb->data);
 587        fctl = wlhdr->frame_control;
 588
 589        if (macstat & B43_RX_MAC_DEC) {
 590                unsigned int keyidx;
 591                int wlhdr_len;
 592
 593                keyidx = ((macstat & B43_RX_MAC_KEYIDX)
 594                          >> B43_RX_MAC_KEYIDX_SHIFT);
 595                /* We must adjust the key index here. We want the "physical"
 596                 * key index, but the ucode passed it slightly different.
 597                 */
 598                keyidx = b43_kidx_to_raw(dev, keyidx);
 599                B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key));
 600
 601                if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
 602                        wlhdr_len = ieee80211_hdrlen(fctl);
 603                        if (unlikely(skb->len < (wlhdr_len + 3))) {
 604                                b43dbg(dev->wl,
 605                                       "RX: Packet size underrun (3)\n");
 606                                goto drop;
 607                        }
 608                        status.flag |= RX_FLAG_DECRYPTED;
 609                }
 610        }
 611
 612        /* Link quality statistics */
 613        status.noise = dev->stats.link_noise;
 614        if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
 615//              s8 rssi = max(rxhdr->power0, rxhdr->power1);
 616                //TODO: Find out what the rssi value is (dBm or percentage?)
 617                //      and also find out what the maximum possible value is.
 618                //      Fill status.ssi and status.signal fields.
 619        } else {
 620                status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
 621                                                  (phystat0 & B43_RX_PHYST0_OFDM),
 622                                                  (phystat0 & B43_RX_PHYST0_GAINCTL),
 623                                                  (phystat3 & B43_RX_PHYST3_TRSTATE));
 624                status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
 625        }
 626
 627        if (phystat0 & B43_RX_PHYST0_OFDM)
 628                status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
 629                                                phytype == B43_PHYTYPE_A);
 630        else
 631                status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
 632        if (unlikely(status.rate_idx == -1)) {
 633                /* PLCP seems to be corrupted.
 634                 * Drop the frame, if we are not interested in corrupted frames. */
 635                if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
 636                        goto drop;
 637        }
 638        status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
 639
 640        /*
 641         * All frames on monitor interfaces and beacons always need a full
 642         * 64-bit timestamp. Monitor interfaces need it for diagnostic
 643         * purposes and beacons for IBSS merging.
 644         * This code assumes we get to process the packet within 16 bits
 645         * of timestamp, i.e. about 65 milliseconds after the PHY received
 646         * the first symbol.
 647         */
 648        if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
 649                u16 low_mactime_now;
 650
 651                b43_tsf_read(dev, &status.mactime);
 652                low_mactime_now = status.mactime;
 653                status.mactime = status.mactime & ~0xFFFFULL;
 654                status.mactime += mactime;
 655                if (low_mactime_now <= mactime)
 656                        status.mactime -= 0x10000;
 657                status.flag |= RX_FLAG_TSFT;
 658        }
 659
 660        chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
 661        switch (chanstat & B43_RX_CHAN_PHYTYPE) {
 662        case B43_PHYTYPE_A:
 663                status.band = IEEE80211_BAND_5GHZ;
 664                B43_WARN_ON(1);
 665                /* FIXME: We don't really know which value the "chanid" contains.
 666                 *        So the following assignment might be wrong. */
 667                status.freq = b43_channel_to_freq_5ghz(chanid);
 668                break;
 669        case B43_PHYTYPE_G:
 670                status.band = IEEE80211_BAND_2GHZ;
 671                /* chanid is the radio channel cookie value as used
 672                 * to tune the radio. */
 673                status.freq = chanid + 2400;
 674                break;
 675        case B43_PHYTYPE_N:
 676        case B43_PHYTYPE_LP:
 677                /* chanid is the SHM channel cookie. Which is the plain
 678                 * channel number in b43. */
 679                if (chanstat & B43_RX_CHAN_5GHZ) {
 680                        status.band = IEEE80211_BAND_5GHZ;
 681                        status.freq = b43_freq_to_channel_5ghz(chanid);
 682                } else {
 683                        status.band = IEEE80211_BAND_2GHZ;
 684                        status.freq = b43_freq_to_channel_2ghz(chanid);
 685                }
 686                break;
 687        default:
 688                B43_WARN_ON(1);
 689                goto drop;
 690        }
 691
 692        memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
 693
 694        local_bh_disable();
 695        ieee80211_rx(dev->wl->hw, skb);
 696        local_bh_enable();
 697
 698#if B43_DEBUG
 699        dev->rx_count++;
 700#endif
 701        return;
 702drop:
 703        b43dbg(dev->wl, "RX: Packet dropped\n");
 704        dev_kfree_skb_any(skb);
 705}
 706
 707void b43_handle_txstatus(struct b43_wldev *dev,
 708                         const struct b43_txstatus *status)
 709{
 710        b43_debugfs_log_txstat(dev, status);
 711
 712        if (status->intermediate)
 713                return;
 714        if (status->for_ampdu)
 715                return;
 716        if (!status->acked)
 717                dev->wl->ieee_stats.dot11ACKFailureCount++;
 718        if (status->rts_count) {
 719                if (status->rts_count == 0xF)   //FIXME
 720                        dev->wl->ieee_stats.dot11RTSFailureCount++;
 721                else
 722                        dev->wl->ieee_stats.dot11RTSSuccessCount++;
 723        }
 724
 725        if (b43_using_pio_transfers(dev))
 726                b43_pio_handle_txstatus(dev, status);
 727        else
 728                b43_dma_handle_txstatus(dev, status);
 729
 730        b43_phy_txpower_check(dev, 0);
 731}
 732
 733/* Fill out the mac80211 TXstatus report based on the b43-specific
 734 * txstatus report data. This returns a boolean whether the frame was
 735 * successfully transmitted. */
 736bool b43_fill_txstatus_report(struct b43_wldev *dev,
 737                              struct ieee80211_tx_info *report,
 738                              const struct b43_txstatus *status)
 739{
 740        bool frame_success = 1;
 741        int retry_limit;
 742
 743        /* preserve the confiured retry limit before clearing the status
 744         * The xmit function has overwritten the rc's value with the actual
 745         * retry limit done by the hardware */
 746        retry_limit = report->status.rates[0].count;
 747        ieee80211_tx_info_clear_status(report);
 748
 749        if (status->acked) {
 750                /* The frame was ACKed. */
 751                report->flags |= IEEE80211_TX_STAT_ACK;
 752        } else {
 753                /* The frame was not ACKed... */
 754                if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
 755                        /* ...but we expected an ACK. */
 756                        frame_success = 0;
 757                }
 758        }
 759        if (status->frame_count == 0) {
 760                /* The frame was not transmitted at all. */
 761                report->status.rates[0].count = 0;
 762        } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
 763                /*
 764                 * If the short retries (RTS, not data frame) have exceeded
 765                 * the limit, the hw will not have tried the selected rate,
 766                 * but will have used the fallback rate instead.
 767                 * Don't let the rate control count attempts for the selected
 768                 * rate in this case, otherwise the statistics will be off.
 769                 */
 770                report->status.rates[0].count = 0;
 771                report->status.rates[1].count = status->frame_count;
 772        } else {
 773                if (status->frame_count > retry_limit) {
 774                        report->status.rates[0].count = retry_limit;
 775                        report->status.rates[1].count = status->frame_count -
 776                                        retry_limit;
 777
 778                } else {
 779                        report->status.rates[0].count = status->frame_count;
 780                        report->status.rates[1].idx = -1;
 781                }
 782        }
 783
 784        return frame_success;
 785}
 786
 787/* Stop any TX operation on the device (suspend the hardware queues) */
 788void b43_tx_suspend(struct b43_wldev *dev)
 789{
 790        if (b43_using_pio_transfers(dev))
 791                b43_pio_tx_suspend(dev);
 792        else
 793                b43_dma_tx_suspend(dev);
 794}
 795
 796/* Resume any TX operation on the device (resume the hardware queues) */
 797void b43_tx_resume(struct b43_wldev *dev)
 798{
 799        if (b43_using_pio_transfers(dev))
 800                b43_pio_tx_resume(dev);
 801        else
 802                b43_dma_tx_resume(dev);
 803}
 804