3   Broadcom B43 wireless driver
 
   5   Transmission (TX/RX) related functions.
 
   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>
 
  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.
 
  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.
 
  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.
 
  31 #include "phy_common.h"
 
  36 /* Extract the bitrate index out of a CCK PLCP header. */
 
  37 static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
 
  39         switch (plcp->raw[0]) {
 
  53 /* Extract the bitrate index out of an OFDM PLCP header. */
 
  54 static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
 
  56         int base = aphy ? 0 : 4;
 
  58         switch (plcp->raw[0] & 0xF) {
 
  80 u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
 
  83         case B43_CCK_RATE_1MB:
 
  85         case B43_CCK_RATE_2MB:
 
  87         case B43_CCK_RATE_5MB:
 
  89         case B43_CCK_RATE_11MB:
 
  96 u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate)
 
  99         case B43_OFDM_RATE_6MB:
 
 101         case B43_OFDM_RATE_9MB:
 
 103         case B43_OFDM_RATE_12MB:
 
 105         case B43_OFDM_RATE_18MB:
 
 107         case B43_OFDM_RATE_24MB:
 
 109         case B43_OFDM_RATE_36MB:
 
 111         case B43_OFDM_RATE_48MB:
 
 113         case B43_OFDM_RATE_54MB:
 
 120 void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
 
 121                            const u16 octets, const u8 bitrate)
 
 123         __le32 *data = &(plcp->data);
 
 124         __u8 *raw = plcp->raw;
 
 126         if (b43_is_ofdm_rate(bitrate)) {
 
 129                 d = b43_plcp_get_ratecode_ofdm(bitrate);
 
 130                 B43_WARN_ON(octets & 0xF000);
 
 132                 *data = cpu_to_le32(d);
 
 136                 plen = octets * 16 / bitrate;
 
 137                 if ((octets * 16 % bitrate) > 0) {
 
 139                         if ((bitrate == B43_CCK_RATE_11MB)
 
 140                             && ((octets * 8 % 11) < 4)) {
 
 146                 *data |= cpu_to_le32(plen << 16);
 
 147                 raw[0] = b43_plcp_get_ratecode_cck(bitrate);
 
 151 static u8 b43_calc_fallback_rate(u8 bitrate)
 
 154         case B43_CCK_RATE_1MB:
 
 155                 return B43_CCK_RATE_1MB;
 
 156         case B43_CCK_RATE_2MB:
 
 157                 return B43_CCK_RATE_1MB;
 
 158         case B43_CCK_RATE_5MB:
 
 159                 return B43_CCK_RATE_2MB;
 
 160         case B43_CCK_RATE_11MB:
 
 161                 return B43_CCK_RATE_5MB;
 
 162         case B43_OFDM_RATE_6MB:
 
 163                 return B43_CCK_RATE_5MB;
 
 164         case B43_OFDM_RATE_9MB:
 
 165                 return B43_OFDM_RATE_6MB;
 
 166         case B43_OFDM_RATE_12MB:
 
 167                 return B43_OFDM_RATE_9MB;
 
 168         case B43_OFDM_RATE_18MB:
 
 169                 return B43_OFDM_RATE_12MB;
 
 170         case B43_OFDM_RATE_24MB:
 
 171                 return B43_OFDM_RATE_18MB;
 
 172         case B43_OFDM_RATE_36MB:
 
 173                 return B43_OFDM_RATE_24MB;
 
 174         case B43_OFDM_RATE_48MB:
 
 175                 return B43_OFDM_RATE_36MB;
 
 176         case B43_OFDM_RATE_54MB:
 
 177                 return B43_OFDM_RATE_48MB;
 
 183 /* Generate a TX data header. */
 
 184 int b43_generate_txhdr(struct b43_wldev *dev,
 
 186                        const unsigned char *fragment_data,
 
 187                        unsigned int fragment_len,
 
 188                        const struct ieee80211_tx_info *info,
 
 191         struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
 
 192         const struct b43_phy *phy = &dev->phy;
 
 193         const struct ieee80211_hdr *wlhdr =
 
 194             (const struct ieee80211_hdr *)fragment_data;
 
 195         int use_encryption = !!info->control.hw_key;
 
 196         __le16 fctl = wlhdr->frame_control;
 
 197         struct ieee80211_rate *fbrate;
 
 199         int rate_ofdm, rate_fb_ofdm;
 
 200         unsigned int plcp_fragment_len;
 
 204         struct ieee80211_rate *txrate;
 
 206         memset(txhdr, 0, sizeof(*txhdr));
 
 208         txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
 
 209         rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
 
 210         rate_ofdm = b43_is_ofdm_rate(rate);
 
 211         fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : txrate;
 
 212         rate_fb = fbrate->hw_value;
 
 213         rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
 
 216                 txhdr->phy_rate = b43_plcp_get_ratecode_ofdm(rate);
 
 218                 txhdr->phy_rate = b43_plcp_get_ratecode_cck(rate);
 
 219         txhdr->mac_frame_ctl = wlhdr->frame_control;
 
 220         memcpy(txhdr->tx_receiver, wlhdr->addr1, 6);
 
 222         /* Calculate duration for fallback rate */
 
 223         if ((rate_fb == rate) ||
 
 224             (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
 
 225             (wlhdr->duration_id == cpu_to_le16(0))) {
 
 226                 /* If the fallback rate equals the normal rate or the
 
 227                  * dur_id field contains an AID, CFP magic or 0,
 
 228                  * use the original dur_id field. */
 
 229                 txhdr->dur_fb = wlhdr->duration_id;
 
 231                 txhdr->dur_fb = ieee80211_generic_frame_duration(
 
 232                         dev->wl->hw, info->control.vif, fragment_len, fbrate);
 
 235         plcp_fragment_len = fragment_len + FCS_LEN;
 
 236         if (use_encryption) {
 
 237                 u8 key_idx = info->control.hw_key->hw_key_idx;
 
 242                 B43_WARN_ON(key_idx >= dev->max_nr_keys);
 
 243                 key = &(dev->key[key_idx]);
 
 245                 if (unlikely(!key->keyconf)) {
 
 246                         /* This key is invalid. This might only happen
 
 247                          * in a short timeframe after machine resume before
 
 248                          * we were able to reconfigure keys.
 
 249                          * Drop this packet completely. Do not transmit it
 
 250                          * unencrypted to avoid leaking information. */
 
 254                 /* Hardware appends ICV. */
 
 255                 plcp_fragment_len += info->control.hw_key->icv_len;
 
 257                 key_idx = b43_kidx_to_fw(dev, key_idx);
 
 258                 mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
 
 260                 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
 
 262                 wlhdr_len = ieee80211_hdrlen(fctl);
 
 263                 iv_len = min((size_t) info->control.hw_key->iv_len,
 
 264                              ARRAY_SIZE(txhdr->iv));
 
 265                 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
 
 267         if (b43_is_old_txhdr_format(dev)) {
 
 268                 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
 
 269                                       plcp_fragment_len, rate);
 
 271                 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->new_format.plcp),
 
 272                                       plcp_fragment_len, rate);
 
 274         b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
 
 275                               plcp_fragment_len, rate_fb);
 
 277         /* Extra Frame Types */
 
 279                 extra_ft |= B43_TXH_EFT_FB_OFDM;
 
 281                 extra_ft |= B43_TXH_EFT_FB_CCK;
 
 283         /* Set channel radio code. Note that the micrcode ORs 0x100 to
 
 284          * this value before comparing it to the value in SHM, if this
 
 287         txhdr->chan_radio_code = phy->channel;
 
 289         /* PHY TX Control word */
 
 291                 phy_ctl |= B43_TXH_PHY_ENC_OFDM;
 
 293                 phy_ctl |= B43_TXH_PHY_ENC_CCK;
 
 294         if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
 
 295                 phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
 
 297         switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
 
 298         case 0: /* Default */
 
 299                 phy_ctl |= B43_TXH_PHY_ANT01AUTO;
 
 301         case 1: /* Antenna 0 */
 
 302                 phy_ctl |= B43_TXH_PHY_ANT0;
 
 304         case 2: /* Antenna 1 */
 
 305                 phy_ctl |= B43_TXH_PHY_ANT1;
 
 307         case 3: /* Antenna 2 */
 
 308                 phy_ctl |= B43_TXH_PHY_ANT2;
 
 310         case 4: /* Antenna 3 */
 
 311                 phy_ctl |= B43_TXH_PHY_ANT3;
 
 318         if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
 
 319                 mac_ctl |= B43_TXH_MAC_ACK;
 
 320         /* use hardware sequence counter as the non-TID counter */
 
 321         if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
 
 322                 mac_ctl |= B43_TXH_MAC_HWSEQ;
 
 323         if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
 
 324                 mac_ctl |= B43_TXH_MAC_STMSDU;
 
 325         if (phy->type == B43_PHYTYPE_A)
 
 326                 mac_ctl |= B43_TXH_MAC_5GHZ;
 
 327         if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
 
 328                 mac_ctl |= B43_TXH_MAC_LONGFRAME;
 
 330         /* Generate the RTS or CTS-to-self frame */
 
 331         if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
 
 332             (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
 
 334                 struct ieee80211_hdr *hdr;
 
 335                 int rts_rate, rts_rate_fb;
 
 336                 int rts_rate_ofdm, rts_rate_fb_ofdm;
 
 337                 struct b43_plcp_hdr6 *plcp;
 
 338                 struct ieee80211_rate *rts_cts_rate;
 
 340                 rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
 
 342                 rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
 
 343                 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
 
 344                 rts_rate_fb = b43_calc_fallback_rate(rts_rate);
 
 345                 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
 
 347                 if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
 
 348                         struct ieee80211_cts *cts;
 
 350                         if (b43_is_old_txhdr_format(dev)) {
 
 351                                 cts = (struct ieee80211_cts *)
 
 352                                         (txhdr->old_format.rts_frame);
 
 354                                 cts = (struct ieee80211_cts *)
 
 355                                         (txhdr->new_format.rts_frame);
 
 357                         ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
 
 358                                                 fragment_data, fragment_len,
 
 360                         mac_ctl |= B43_TXH_MAC_SENDCTS;
 
 361                         len = sizeof(struct ieee80211_cts);
 
 363                         struct ieee80211_rts *rts;
 
 365                         if (b43_is_old_txhdr_format(dev)) {
 
 366                                 rts = (struct ieee80211_rts *)
 
 367                                         (txhdr->old_format.rts_frame);
 
 369                                 rts = (struct ieee80211_rts *)
 
 370                                         (txhdr->new_format.rts_frame);
 
 372                         ieee80211_rts_get(dev->wl->hw, info->control.vif,
 
 373                                           fragment_data, fragment_len,
 
 375                         mac_ctl |= B43_TXH_MAC_SENDRTS;
 
 376                         len = sizeof(struct ieee80211_rts);
 
 380                 /* Generate the PLCP headers for the RTS/CTS frame */
 
 381                 if (b43_is_old_txhdr_format(dev))
 
 382                         plcp = &txhdr->old_format.rts_plcp;
 
 384                         plcp = &txhdr->new_format.rts_plcp;
 
 385                 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
 
 387                 plcp = &txhdr->rts_plcp_fb;
 
 388                 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
 
 391                 if (b43_is_old_txhdr_format(dev)) {
 
 392                         hdr = (struct ieee80211_hdr *)
 
 393                                 (&txhdr->old_format.rts_frame);
 
 395                         hdr = (struct ieee80211_hdr *)
 
 396                                 (&txhdr->new_format.rts_frame);
 
 398                 txhdr->rts_dur_fb = hdr->duration_id;
 
 401                         extra_ft |= B43_TXH_EFT_RTS_OFDM;
 
 402                         txhdr->phy_rate_rts =
 
 403                             b43_plcp_get_ratecode_ofdm(rts_rate);
 
 405                         extra_ft |= B43_TXH_EFT_RTS_CCK;
 
 406                         txhdr->phy_rate_rts =
 
 407                             b43_plcp_get_ratecode_cck(rts_rate);
 
 409                 if (rts_rate_fb_ofdm)
 
 410                         extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
 
 412                         extra_ft |= B43_TXH_EFT_RTSFB_CCK;
 
 416         if (b43_is_old_txhdr_format(dev))
 
 417                 txhdr->old_format.cookie = cpu_to_le16(cookie);
 
 419                 txhdr->new_format.cookie = cpu_to_le16(cookie);
 
 421         /* Apply the bitfields */
 
 422         txhdr->mac_ctl = cpu_to_le32(mac_ctl);
 
 423         txhdr->phy_ctl = cpu_to_le16(phy_ctl);
 
 424         txhdr->extra_ft = extra_ft;
 
 429 static s8 b43_rssi_postprocess(struct b43_wldev *dev,
 
 430                                u8 in_rssi, int ofdm,
 
 431                                int adjust_2053, int adjust_2050)
 
 433         struct b43_phy *phy = &dev->phy;
 
 434         struct b43_phy_g *gphy = phy->g;
 
 437         switch (phy->radio_ver) {
 
 450                         if (dev->dev->bus->sprom.
 
 451                             boardflags_lo & B43_BFL_RSSI) {
 
 454                                 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
 
 455                                 tmp = gphy->nrssi_lt[in_rssi];
 
 467                         if (phy->type == B43_PHYTYPE_G && adjust_2050)
 
 493 static s8 b43_rssinoise_postprocess(struct b43_wldev *dev, u8 in_rssi)
 
 495         struct b43_phy *phy = &dev->phy;
 
 498         if (phy->type == B43_PHYTYPE_A) {
 
 499                 //TODO: Incomplete specs.
 
 502                 ret = b43_rssi_postprocess(dev, in_rssi, 0, 1, 1);
 
 508 void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 
 510         struct ieee80211_rx_status status;
 
 511         struct b43_plcp_hdr6 *plcp;
 
 512         struct ieee80211_hdr *wlhdr;
 
 513         const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
 
 515         u16 phystat0, phystat3, chanstat, mactime;
 
 521         memset(&status, 0, sizeof(status));
 
 523         /* Get metadata about the frame from the header. */
 
 524         phystat0 = le16_to_cpu(rxhdr->phy_status0);
 
 525         phystat3 = le16_to_cpu(rxhdr->phy_status3);
 
 526         macstat = le32_to_cpu(rxhdr->mac_status);
 
 527         mactime = le16_to_cpu(rxhdr->mac_time);
 
 528         chanstat = le16_to_cpu(rxhdr->channel);
 
 529         phytype = chanstat & B43_RX_CHAN_PHYTYPE;
 
 531         if (macstat & B43_RX_MAC_FCSERR)
 
 532                 dev->wl->ieee_stats.dot11FCSErrorCount++;
 
 533         if (macstat & B43_RX_MAC_DECERR) {
 
 534                 /* Decryption with the given key failed.
 
 535                  * Drop the packet. We also won't be able to decrypt it with
 
 536                  * the key in software. */
 
 540         /* Skip PLCP and padding */
 
 541         padding = (macstat & B43_RX_MAC_PADDING) ? 2 : 0;
 
 542         if (unlikely(skb->len < (sizeof(struct b43_plcp_hdr6) + padding))) {
 
 543                 b43dbg(dev->wl, "RX: Packet size underrun (1)\n");
 
 546         plcp = (struct b43_plcp_hdr6 *)(skb->data + padding);
 
 547         skb_pull(skb, sizeof(struct b43_plcp_hdr6) + padding);
 
 548         /* The skb contains the Wireless Header + payload data now */
 
 549         if (unlikely(skb->len < (2 + 2 + 6 /*minimum hdr */  + FCS_LEN))) {
 
 550                 b43dbg(dev->wl, "RX: Packet size underrun (2)\n");
 
 553         wlhdr = (struct ieee80211_hdr *)(skb->data);
 
 554         fctl = wlhdr->frame_control;
 
 556         if (macstat & B43_RX_MAC_DEC) {
 
 560                 keyidx = ((macstat & B43_RX_MAC_KEYIDX)
 
 561                           >> B43_RX_MAC_KEYIDX_SHIFT);
 
 562                 /* We must adjust the key index here. We want the "physical"
 
 563                  * key index, but the ucode passed it slightly different.
 
 565                 keyidx = b43_kidx_to_raw(dev, keyidx);
 
 566                 B43_WARN_ON(keyidx >= dev->max_nr_keys);
 
 568                 if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
 
 569                         wlhdr_len = ieee80211_hdrlen(fctl);
 
 570                         if (unlikely(skb->len < (wlhdr_len + 3))) {
 
 572                                        "RX: Packet size underrun (3)\n");
 
 575                         status.flag |= RX_FLAG_DECRYPTED;
 
 579         /* Link quality statistics */
 
 580         status.noise = dev->stats.link_noise;
 
 581         if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
 
 582 //              s8 rssi = max(rxhdr->power0, rxhdr->power1);
 
 583                 //TODO: Find out what the rssi value is (dBm or percentage?)
 
 584                 //      and also find out what the maximum possible value is.
 
 585                 //      Fill status.ssi and status.signal fields.
 
 587                 status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
 
 588                                                   (phystat0 & B43_RX_PHYST0_OFDM),
 
 589                                                   (phystat0 & B43_RX_PHYST0_GAINCTL),
 
 590                                                   (phystat3 & B43_RX_PHYST3_TRSTATE));
 
 591                 status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
 
 594         if (phystat0 & B43_RX_PHYST0_OFDM)
 
 595                 status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
 
 596                                                 phytype == B43_PHYTYPE_A);
 
 598                 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
 
 599         status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
 
 602          * All frames on monitor interfaces and beacons always need a full
 
 603          * 64-bit timestamp. Monitor interfaces need it for diagnostic
 
 604          * purposes and beacons for IBSS merging.
 
 605          * This code assumes we get to process the packet within 16 bits
 
 606          * of timestamp, i.e. about 65 milliseconds after the PHY received
 
 609         if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
 
 612                 b43_tsf_read(dev, &status.mactime);
 
 613                 low_mactime_now = status.mactime;
 
 614                 status.mactime = status.mactime & ~0xFFFFULL;
 
 615                 status.mactime += mactime;
 
 616                 if (low_mactime_now <= mactime)
 
 617                         status.mactime -= 0x10000;
 
 618                 status.flag |= RX_FLAG_TSFT;
 
 621         chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
 
 622         switch (chanstat & B43_RX_CHAN_PHYTYPE) {
 
 624                 status.band = IEEE80211_BAND_5GHZ;
 
 626                 /* FIXME: We don't really know which value the "chanid" contains.
 
 627                  *        So the following assignment might be wrong. */
 
 628                 status.freq = b43_channel_to_freq_5ghz(chanid);
 
 631                 status.band = IEEE80211_BAND_2GHZ;
 
 632                 /* chanid is the radio channel cookie value as used
 
 633                  * to tune the radio. */
 
 634                 status.freq = chanid + 2400;
 
 637                 /* chanid is the SHM channel cookie. Which is the plain
 
 638                  * channel number in b43. */
 
 639                 if (chanstat & B43_RX_CHAN_5GHZ) {
 
 640                         status.band = IEEE80211_BAND_5GHZ;
 
 641                         status.freq = b43_freq_to_channel_5ghz(chanid);
 
 643                         status.band = IEEE80211_BAND_2GHZ;
 
 644                         status.freq = b43_freq_to_channel_2ghz(chanid);
 
 652         dev->stats.last_rx = jiffies;
 
 653         ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
 
 657         b43dbg(dev->wl, "RX: Packet dropped\n");
 
 658         dev_kfree_skb_any(skb);
 
 661 void b43_handle_txstatus(struct b43_wldev *dev,
 
 662                          const struct b43_txstatus *status)
 
 664         b43_debugfs_log_txstat(dev, status);
 
 666         if (status->intermediate)
 
 668         if (status->for_ampdu)
 
 671                 dev->wl->ieee_stats.dot11ACKFailureCount++;
 
 672         if (status->rts_count) {
 
 673                 if (status->rts_count == 0xF)   //FIXME
 
 674                         dev->wl->ieee_stats.dot11RTSFailureCount++;
 
 676                         dev->wl->ieee_stats.dot11RTSSuccessCount++;
 
 679         if (b43_using_pio_transfers(dev))
 
 680                 b43_pio_handle_txstatus(dev, status);
 
 682                 b43_dma_handle_txstatus(dev, status);
 
 684         b43_phy_txpower_check(dev, 0);
 
 687 /* Fill out the mac80211 TXstatus report based on the b43-specific
 
 688  * txstatus report data. This returns a boolean whether the frame was
 
 689  * successfully transmitted. */
 
 690 bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
 
 691                               const struct b43_txstatus *status)
 
 693         bool frame_success = 1;
 
 696                 /* The frame was ACKed. */
 
 697                 report->flags |= IEEE80211_TX_STAT_ACK;
 
 699                 /* The frame was not ACKed... */
 
 700                 if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
 
 701                         /* ...but we expected an ACK. */
 
 703                         report->status.excessive_retries = 1;
 
 706         if (status->frame_count == 0) {
 
 707                 /* The frame was not transmitted at all. */
 
 708                 report->status.retry_count = 0;
 
 710                 report->status.retry_count = status->frame_count - 1;
 
 712         return frame_success;
 
 715 /* Stop any TX operation on the device (suspend the hardware queues) */
 
 716 void b43_tx_suspend(struct b43_wldev *dev)
 
 718         if (b43_using_pio_transfers(dev))
 
 719                 b43_pio_tx_suspend(dev);
 
 721                 b43_dma_tx_suspend(dev);
 
 724 /* Resume any TX operation on the device (resume the hardware queues) */
 
 725 void b43_tx_resume(struct b43_wldev *dev)
 
 727         if (b43_using_pio_transfers(dev))
 
 728                 b43_pio_tx_resume(dev);
 
 730                 b43_dma_tx_resume(dev);