root/drivers/net/wireless/broadcom/b43legacy/xmit.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. b43legacy_plcp_get_bitrate_idx_cck
  2. b43legacy_plcp_get_bitrate_idx_ofdm
  3. b43legacy_plcp_get_ratecode_cck
  4. b43legacy_plcp_get_ratecode_ofdm
  5. b43legacy_generate_plcp_hdr
  6. b43legacy_calc_fallback_rate
  7. generate_txhdr_fw3
  8. b43legacy_generate_txhdr
  9. b43legacy_rssi_postprocess
  10. b43legacy_rx
  11. b43legacy_handle_txstatus
  12. b43legacy_handle_hwtxstatus
  13. b43legacy_tx_suspend
  14. b43legacy_tx_resume
  15. b43legacy_qos_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3 
   4   Broadcom B43legacy wireless driver
   5 
   6   Transmission (TX/RX) related functions.
   7 
   8   Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
   9   Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it>
  10   Copyright (C) 2005, 2006 Michael Buesch <m@bues.ch>
  11   Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
  12   Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
  13   Copyright (C) 2007 Larry Finger <Larry.Finger@lwfinger.net>
  14 
  15 
  16 */
  17 
  18 #include <net/dst.h>
  19 
  20 #include "xmit.h"
  21 #include "phy.h"
  22 #include "dma.h"
  23 #include "pio.h"
  24 
  25 
  26 /* Extract the bitrate out of a CCK PLCP header. */
  27 static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp)
  28 {
  29         switch (plcp->raw[0]) {
  30         case 0x0A:
  31                 return 0;
  32         case 0x14:
  33                 return 1;
  34         case 0x37:
  35                 return 2;
  36         case 0x6E:
  37                 return 3;
  38         }
  39         B43legacy_BUG_ON(1);
  40         return -1;
  41 }
  42 
  43 /* Extract the bitrate out of an OFDM PLCP header. */
  44 static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp,
  45                                               bool aphy)
  46 {
  47         int base = aphy ? 0 : 4;
  48 
  49         switch (plcp->raw[0] & 0xF) {
  50         case 0xB:
  51                 return base + 0;
  52         case 0xF:
  53                 return base + 1;
  54         case 0xA:
  55                 return base + 2;
  56         case 0xE:
  57                 return base + 3;
  58         case 0x9:
  59                 return base + 4;
  60         case 0xD:
  61                 return base + 5;
  62         case 0x8:
  63                 return base + 6;
  64         case 0xC:
  65                 return base + 7;
  66         }
  67         B43legacy_BUG_ON(1);
  68         return -1;
  69 }
  70 
  71 u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate)
  72 {
  73         switch (bitrate) {
  74         case B43legacy_CCK_RATE_1MB:
  75                 return 0x0A;
  76         case B43legacy_CCK_RATE_2MB:
  77                 return 0x14;
  78         case B43legacy_CCK_RATE_5MB:
  79                 return 0x37;
  80         case B43legacy_CCK_RATE_11MB:
  81                 return 0x6E;
  82         }
  83         B43legacy_BUG_ON(1);
  84         return 0;
  85 }
  86 
  87 u8 b43legacy_plcp_get_ratecode_ofdm(const u8 bitrate)
  88 {
  89         switch (bitrate) {
  90         case B43legacy_OFDM_RATE_6MB:
  91                 return 0xB;
  92         case B43legacy_OFDM_RATE_9MB:
  93                 return 0xF;
  94         case B43legacy_OFDM_RATE_12MB:
  95                 return 0xA;
  96         case B43legacy_OFDM_RATE_18MB:
  97                 return 0xE;
  98         case B43legacy_OFDM_RATE_24MB:
  99                 return 0x9;
 100         case B43legacy_OFDM_RATE_36MB:
 101                 return 0xD;
 102         case B43legacy_OFDM_RATE_48MB:
 103                 return 0x8;
 104         case B43legacy_OFDM_RATE_54MB:
 105                 return 0xC;
 106         }
 107         B43legacy_BUG_ON(1);
 108         return 0;
 109 }
 110 
 111 void b43legacy_generate_plcp_hdr(struct b43legacy_plcp_hdr4 *plcp,
 112                                  const u16 octets, const u8 bitrate)
 113 {
 114         __le32 *data = &(plcp->data);
 115         __u8 *raw = plcp->raw;
 116 
 117         if (b43legacy_is_ofdm_rate(bitrate)) {
 118                 u16 d;
 119 
 120                 d = b43legacy_plcp_get_ratecode_ofdm(bitrate);
 121                 B43legacy_WARN_ON(octets & 0xF000);
 122                 d |= (octets << 5);
 123                 *data = cpu_to_le32(d);
 124         } else {
 125                 u32 plen;
 126 
 127                 plen = octets * 16 / bitrate;
 128                 if ((octets * 16 % bitrate) > 0) {
 129                         plen++;
 130                         if ((bitrate == B43legacy_CCK_RATE_11MB)
 131                             && ((octets * 8 % 11) < 4))
 132                                 raw[1] = 0x84;
 133                         else
 134                                 raw[1] = 0x04;
 135                 } else
 136                         raw[1] = 0x04;
 137                 *data |= cpu_to_le32(plen << 16);
 138                 raw[0] = b43legacy_plcp_get_ratecode_cck(bitrate);
 139         }
 140 }
 141 
 142 static u8 b43legacy_calc_fallback_rate(u8 bitrate)
 143 {
 144         switch (bitrate) {
 145         case B43legacy_CCK_RATE_1MB:
 146                 return B43legacy_CCK_RATE_1MB;
 147         case B43legacy_CCK_RATE_2MB:
 148                 return B43legacy_CCK_RATE_1MB;
 149         case B43legacy_CCK_RATE_5MB:
 150                 return B43legacy_CCK_RATE_2MB;
 151         case B43legacy_CCK_RATE_11MB:
 152                 return B43legacy_CCK_RATE_5MB;
 153         case B43legacy_OFDM_RATE_6MB:
 154                 return B43legacy_CCK_RATE_5MB;
 155         case B43legacy_OFDM_RATE_9MB:
 156                 return B43legacy_OFDM_RATE_6MB;
 157         case B43legacy_OFDM_RATE_12MB:
 158                 return B43legacy_OFDM_RATE_9MB;
 159         case B43legacy_OFDM_RATE_18MB:
 160                 return B43legacy_OFDM_RATE_12MB;
 161         case B43legacy_OFDM_RATE_24MB:
 162                 return B43legacy_OFDM_RATE_18MB;
 163         case B43legacy_OFDM_RATE_36MB:
 164                 return B43legacy_OFDM_RATE_24MB;
 165         case B43legacy_OFDM_RATE_48MB:
 166                 return B43legacy_OFDM_RATE_36MB;
 167         case B43legacy_OFDM_RATE_54MB:
 168                 return B43legacy_OFDM_RATE_48MB;
 169         }
 170         B43legacy_BUG_ON(1);
 171         return 0;
 172 }
 173 
 174 static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
 175                                struct b43legacy_txhdr_fw3 *txhdr,
 176                                const unsigned char *fragment_data,
 177                                unsigned int fragment_len,
 178                                struct ieee80211_tx_info *info,
 179                                u16 cookie)
 180 {
 181         const struct ieee80211_hdr *wlhdr;
 182         int use_encryption = !!info->control.hw_key;
 183         u8 rate;
 184         struct ieee80211_rate *rate_fb;
 185         int rate_ofdm;
 186         int rate_fb_ofdm;
 187         unsigned int plcp_fragment_len;
 188         u32 mac_ctl = 0;
 189         u16 phy_ctl = 0;
 190         struct ieee80211_rate *tx_rate;
 191         struct ieee80211_tx_rate *rates;
 192 
 193         wlhdr = (const struct ieee80211_hdr *)fragment_data;
 194 
 195         memset(txhdr, 0, sizeof(*txhdr));
 196 
 197         tx_rate = ieee80211_get_tx_rate(dev->wl->hw, info);
 198 
 199         rate = tx_rate->hw_value;
 200         rate_ofdm = b43legacy_is_ofdm_rate(rate);
 201         rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : tx_rate;
 202         rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
 203 
 204         txhdr->mac_frame_ctl = wlhdr->frame_control;
 205         memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN);
 206 
 207         /* Calculate duration for fallback rate */
 208         if ((rate_fb->hw_value == rate) ||
 209             (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
 210             (wlhdr->duration_id == cpu_to_le16(0))) {
 211                 /* If the fallback rate equals the normal rate or the
 212                  * dur_id field contains an AID, CFP magic or 0,
 213                  * use the original dur_id field. */
 214                 txhdr->dur_fb = wlhdr->duration_id;
 215         } else {
 216                 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
 217                                                          info->control.vif,
 218                                                          info->band,
 219                                                          fragment_len,
 220                                                          rate_fb);
 221         }
 222 
 223         plcp_fragment_len = fragment_len + FCS_LEN;
 224         if (use_encryption) {
 225                 u8 key_idx = info->control.hw_key->hw_key_idx;
 226                 struct b43legacy_key *key;
 227                 int wlhdr_len;
 228                 size_t iv_len;
 229 
 230                 B43legacy_WARN_ON(key_idx >= dev->max_nr_keys);
 231                 key = &(dev->key[key_idx]);
 232 
 233                 if (key->enabled) {
 234                         /* Hardware appends ICV. */
 235                         plcp_fragment_len += info->control.hw_key->icv_len;
 236 
 237                         key_idx = b43legacy_kidx_to_fw(dev, key_idx);
 238                         mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
 239                                    B43legacy_TX4_MAC_KEYIDX;
 240                         mac_ctl |= (key->algorithm <<
 241                                    B43legacy_TX4_MAC_KEYALG_SHIFT) &
 242                                    B43legacy_TX4_MAC_KEYALG;
 243                         wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control);
 244                         iv_len = min_t(size_t, info->control.hw_key->iv_len,
 245                                      ARRAY_SIZE(txhdr->iv));
 246                         memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
 247                 } else {
 248                         /* This key is invalid. This might only happen
 249                          * in a short timeframe after machine resume before
 250                          * we were able to reconfigure keys.
 251                          * Drop this packet completely. Do not transmit it
 252                          * unencrypted to avoid leaking information. */
 253                         return -ENOKEY;
 254                 }
 255         }
 256         b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
 257                                     (&txhdr->plcp), plcp_fragment_len,
 258                                     rate);
 259         b43legacy_generate_plcp_hdr(&txhdr->plcp_fb, plcp_fragment_len,
 260                                     rate_fb->hw_value);
 261 
 262         /* PHY TX Control word */
 263         if (rate_ofdm)
 264                 phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM;
 265         if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
 266                 phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
 267         phy_ctl |= B43legacy_TX4_PHY_ANTLAST;
 268 
 269         /* MAC control */
 270         rates = info->control.rates;
 271         if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
 272                 mac_ctl |= B43legacy_TX4_MAC_ACK;
 273         if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
 274                 mac_ctl |= B43legacy_TX4_MAC_HWSEQ;
 275         if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
 276                 mac_ctl |= B43legacy_TX4_MAC_STMSDU;
 277         if (rate_fb_ofdm)
 278                 mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM;
 279 
 280         /* Overwrite rates[0].count to make the retry calculation
 281          * in the tx status easier. need the actual retry limit to
 282          * detect whether the fallback rate was used.
 283          */
 284         if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
 285             (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
 286                 rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
 287                 mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
 288         } else {
 289                 rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
 290         }
 291 
 292         /* Generate the RTS or CTS-to-self frame */
 293         if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
 294             (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
 295                 unsigned int len;
 296                 struct ieee80211_hdr *hdr;
 297                 int rts_rate;
 298                 int rts_rate_fb;
 299                 int rts_rate_fb_ofdm;
 300 
 301                 rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value;
 302                 rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
 303                 rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
 304                 if (rts_rate_fb_ofdm)
 305                         mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM;
 306 
 307                 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
 308                         ieee80211_ctstoself_get(dev->wl->hw,
 309                                                 info->control.vif,
 310                                                 fragment_data,
 311                                                 fragment_len, info,
 312                                                 (struct ieee80211_cts *)
 313                                                 (txhdr->rts_frame));
 314                         mac_ctl |= B43legacy_TX4_MAC_SENDCTS;
 315                         len = sizeof(struct ieee80211_cts);
 316                 } else {
 317                         ieee80211_rts_get(dev->wl->hw,
 318                                           info->control.vif,
 319                                           fragment_data, fragment_len, info,
 320                                           (struct ieee80211_rts *)
 321                                           (txhdr->rts_frame));
 322                         mac_ctl |= B43legacy_TX4_MAC_SENDRTS;
 323                         len = sizeof(struct ieee80211_rts);
 324                 }
 325                 len += FCS_LEN;
 326                 b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
 327                                             (&txhdr->rts_plcp),
 328                                             len, rts_rate);
 329                 b43legacy_generate_plcp_hdr(&txhdr->rts_plcp_fb,
 330                                             len, rts_rate_fb);
 331                 hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame);
 332                 txhdr->rts_dur_fb = hdr->duration_id;
 333         }
 334 
 335         /* Magic cookie */
 336         txhdr->cookie = cpu_to_le16(cookie);
 337 
 338         /* Apply the bitfields */
 339         txhdr->mac_ctl = cpu_to_le32(mac_ctl);
 340         txhdr->phy_ctl = cpu_to_le16(phy_ctl);
 341 
 342         return 0;
 343 }
 344 
 345 int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
 346                               u8 *txhdr,
 347                               const unsigned char *fragment_data,
 348                               unsigned int fragment_len,
 349                               struct ieee80211_tx_info *info,
 350                               u16 cookie)
 351 {
 352         return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
 353                            fragment_data, fragment_len,
 354                            info, cookie);
 355 }
 356 
 357 static s8 b43legacy_rssi_postprocess(struct b43legacy_wldev *dev,
 358                                      u8 in_rssi, int ofdm,
 359                                      int adjust_2053, int adjust_2050)
 360 {
 361         struct b43legacy_phy *phy = &dev->phy;
 362         s32 tmp;
 363 
 364         switch (phy->radio_ver) {
 365         case 0x2050:
 366                 if (ofdm) {
 367                         tmp = in_rssi;
 368                         if (tmp > 127)
 369                                 tmp -= 256;
 370                         tmp *= 73;
 371                         tmp /= 64;
 372                         if (adjust_2050)
 373                                 tmp += 25;
 374                         else
 375                                 tmp -= 3;
 376                 } else {
 377                         if (dev->dev->bus->sprom.boardflags_lo
 378                             & B43legacy_BFL_RSSI) {
 379                                 if (in_rssi > 63)
 380                                         in_rssi = 63;
 381                                 tmp = phy->nrssi_lt[in_rssi];
 382                                 tmp = 31 - tmp;
 383                                 tmp *= -131;
 384                                 tmp /= 128;
 385                                 tmp -= 57;
 386                         } else {
 387                                 tmp = in_rssi;
 388                                 tmp = 31 - tmp;
 389                                 tmp *= -149;
 390                                 tmp /= 128;
 391                                 tmp -= 68;
 392                         }
 393                         if (phy->type == B43legacy_PHYTYPE_G &&
 394                             adjust_2050)
 395                                 tmp += 25;
 396                 }
 397                 break;
 398         case 0x2060:
 399                 if (in_rssi > 127)
 400                         tmp = in_rssi - 256;
 401                 else
 402                         tmp = in_rssi;
 403                 break;
 404         default:
 405                 tmp = in_rssi;
 406                 tmp -= 11;
 407                 tmp *= 103;
 408                 tmp /= 64;
 409                 if (adjust_2053)
 410                         tmp -= 109;
 411                 else
 412                         tmp -= 83;
 413         }
 414 
 415         return (s8)tmp;
 416 }
 417 
 418 void b43legacy_rx(struct b43legacy_wldev *dev,
 419                   struct sk_buff *skb,
 420                   const void *_rxhdr)
 421 {
 422         struct ieee80211_rx_status status;
 423         struct b43legacy_plcp_hdr6 *plcp;
 424         struct ieee80211_hdr *wlhdr;
 425         const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr;
 426         __le16 fctl;
 427         u16 phystat0;
 428         u16 phystat3;
 429         u16 chanstat;
 430         u16 mactime;
 431         u32 macstat;
 432         u16 chanid;
 433         u8 jssi;
 434         int padding;
 435 
 436         memset(&status, 0, sizeof(status));
 437 
 438         /* Get metadata about the frame from the header. */
 439         phystat0 = le16_to_cpu(rxhdr->phy_status0);
 440         phystat3 = le16_to_cpu(rxhdr->phy_status3);
 441         jssi = rxhdr->jssi;
 442         macstat = le16_to_cpu(rxhdr->mac_status);
 443         mactime = le16_to_cpu(rxhdr->mac_time);
 444         chanstat = le16_to_cpu(rxhdr->channel);
 445 
 446         if (macstat & B43legacy_RX_MAC_FCSERR)
 447                 dev->wl->ieee_stats.dot11FCSErrorCount++;
 448 
 449         /* Skip PLCP and padding */
 450         padding = (macstat & B43legacy_RX_MAC_PADDING) ? 2 : 0;
 451         if (unlikely(skb->len < (sizeof(struct b43legacy_plcp_hdr6) +
 452             padding))) {
 453                 b43legacydbg(dev->wl, "RX: Packet size underrun (1)\n");
 454                 goto drop;
 455         }
 456         plcp = (struct b43legacy_plcp_hdr6 *)(skb->data + padding);
 457         skb_pull(skb, sizeof(struct b43legacy_plcp_hdr6) + padding);
 458         /* The skb contains the Wireless Header + payload data now */
 459         if (unlikely(skb->len < (2+2+6/*minimum hdr*/ + FCS_LEN))) {
 460                 b43legacydbg(dev->wl, "RX: Packet size underrun (2)\n");
 461                 goto drop;
 462         }
 463         wlhdr = (struct ieee80211_hdr *)(skb->data);
 464         fctl = wlhdr->frame_control;
 465 
 466         if ((macstat & B43legacy_RX_MAC_DEC) &&
 467             !(macstat & B43legacy_RX_MAC_DECERR)) {
 468                 unsigned int keyidx;
 469                 int wlhdr_len;
 470                 int iv_len;
 471                 int icv_len;
 472 
 473                 keyidx = ((macstat & B43legacy_RX_MAC_KEYIDX)
 474                           >> B43legacy_RX_MAC_KEYIDX_SHIFT);
 475                 /* We must adjust the key index here. We want the "physical"
 476                  * key index, but the ucode passed it slightly different.
 477                  */
 478                 keyidx = b43legacy_kidx_to_raw(dev, keyidx);
 479                 B43legacy_WARN_ON(keyidx >= dev->max_nr_keys);
 480 
 481                 if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) {
 482                         /* Remove PROTECTED flag to mark it as decrypted. */
 483                         B43legacy_WARN_ON(!ieee80211_has_protected(fctl));
 484                         fctl &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 485                         wlhdr->frame_control = fctl;
 486 
 487                         wlhdr_len = ieee80211_hdrlen(fctl);
 488                         if (unlikely(skb->len < (wlhdr_len + 3))) {
 489                                 b43legacydbg(dev->wl, "RX: Packet size"
 490                                              " underrun3\n");
 491                                 goto drop;
 492                         }
 493                         if (skb->data[wlhdr_len + 3] & (1 << 5)) {
 494                                 /* The Ext-IV Bit is set in the "KeyID"
 495                                  * octet of the IV.
 496                                  */
 497                                 iv_len = 8;
 498                                 icv_len = 8;
 499                         } else {
 500                                 iv_len = 4;
 501                                 icv_len = 4;
 502                         }
 503                         if (unlikely(skb->len < (wlhdr_len + iv_len +
 504                             icv_len))) {
 505                                 b43legacydbg(dev->wl, "RX: Packet size"
 506                                              " underrun4\n");
 507                                 goto drop;
 508                         }
 509                         /* Remove the IV */
 510                         memmove(skb->data + iv_len, skb->data, wlhdr_len);
 511                         skb_pull(skb, iv_len);
 512                         /* Remove the ICV */
 513                         skb_trim(skb, skb->len - icv_len);
 514 
 515                         status.flag |= RX_FLAG_DECRYPTED;
 516                 }
 517         }
 518 
 519         status.signal = b43legacy_rssi_postprocess(dev, jssi,
 520                                       (phystat0 & B43legacy_RX_PHYST0_OFDM),
 521                                       (phystat0 & B43legacy_RX_PHYST0_GAINCTL),
 522                                       (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
 523         /* change to support A PHY */
 524         if (phystat0 & B43legacy_RX_PHYST0_OFDM)
 525                 status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
 526         else
 527                 status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp);
 528         status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
 529 
 530         /*
 531          * All frames on monitor interfaces and beacons always need a full
 532          * 64-bit timestamp. Monitor interfaces need it for diagnostic
 533          * purposes and beacons for IBSS merging.
 534          * This code assumes we get to process the packet within 16 bits
 535          * of timestamp, i.e. about 65 milliseconds after the PHY received
 536          * the first symbol.
 537          */
 538         if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
 539                 u16 low_mactime_now;
 540 
 541                 b43legacy_tsf_read(dev, &status.mactime);
 542                 low_mactime_now = status.mactime;
 543                 status.mactime = status.mactime & ~0xFFFFULL;
 544                 status.mactime += mactime;
 545                 if (low_mactime_now <= mactime)
 546                         status.mactime -= 0x10000;
 547                 status.flag |= RX_FLAG_MACTIME_START;
 548         }
 549 
 550         chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
 551                   B43legacy_RX_CHAN_ID_SHIFT;
 552         switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) {
 553         case B43legacy_PHYTYPE_B:
 554         case B43legacy_PHYTYPE_G:
 555                 status.band = NL80211_BAND_2GHZ;
 556                 status.freq = chanid + 2400;
 557                 break;
 558         default:
 559                 b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
 560                        chanstat);
 561         }
 562 
 563         memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
 564         ieee80211_rx_irqsafe(dev->wl->hw, skb);
 565 
 566         return;
 567 drop:
 568         b43legacydbg(dev->wl, "RX: Packet dropped\n");
 569         dev_kfree_skb_any(skb);
 570 }
 571 
 572 void b43legacy_handle_txstatus(struct b43legacy_wldev *dev,
 573                              const struct b43legacy_txstatus *status)
 574 {
 575         b43legacy_debugfs_log_txstat(dev, status);
 576 
 577         if (status->intermediate)
 578                 return;
 579         if (status->for_ampdu)
 580                 return;
 581         if (!status->acked)
 582                 dev->wl->ieee_stats.dot11ACKFailureCount++;
 583         if (status->rts_count) {
 584                 if (status->rts_count == 0xF) /* FIXME */
 585                         dev->wl->ieee_stats.dot11RTSFailureCount++;
 586                 else
 587                         dev->wl->ieee_stats.dot11RTSSuccessCount++;
 588         }
 589 
 590         if (b43legacy_using_pio(dev))
 591                 b43legacy_pio_handle_txstatus(dev, status);
 592         else
 593                 b43legacy_dma_handle_txstatus(dev, status);
 594 }
 595 
 596 /* Handle TX status report as received through DMA/PIO queues */
 597 void b43legacy_handle_hwtxstatus(struct b43legacy_wldev *dev,
 598                                  const struct b43legacy_hwtxstatus *hw)
 599 {
 600         struct b43legacy_txstatus status;
 601         u8 tmp;
 602 
 603         status.cookie = le16_to_cpu(hw->cookie);
 604         status.seq = le16_to_cpu(hw->seq);
 605         status.phy_stat = hw->phy_stat;
 606         tmp = hw->count;
 607         status.frame_count = (tmp >> 4);
 608         status.rts_count = (tmp & 0x0F);
 609         tmp = hw->flags << 1;
 610         status.supp_reason = ((tmp & 0x1C) >> 2);
 611         status.pm_indicated = !!(tmp & 0x80);
 612         status.intermediate = !!(tmp & 0x40);
 613         status.for_ampdu = !!(tmp & 0x20);
 614         status.acked = !!(tmp & 0x02);
 615 
 616         b43legacy_handle_txstatus(dev, &status);
 617 }
 618 
 619 /* Stop any TX operation on the device (suspend the hardware queues) */
 620 void b43legacy_tx_suspend(struct b43legacy_wldev *dev)
 621 {
 622         if (b43legacy_using_pio(dev))
 623                 b43legacy_pio_freeze_txqueues(dev);
 624         else
 625                 b43legacy_dma_tx_suspend(dev);
 626 }
 627 
 628 /* Resume any TX operation on the device (resume the hardware queues) */
 629 void b43legacy_tx_resume(struct b43legacy_wldev *dev)
 630 {
 631         if (b43legacy_using_pio(dev))
 632                 b43legacy_pio_thaw_txqueues(dev);
 633         else
 634                 b43legacy_dma_tx_resume(dev);
 635 }
 636 
 637 /* Initialize the QoS parameters */
 638 void b43legacy_qos_init(struct b43legacy_wldev *dev)
 639 {
 640         /* FIXME: This function must probably be called from the mac80211
 641          * config callback. */
 642 return;
 643 
 644         b43legacy_hf_write(dev, b43legacy_hf_read(dev) | B43legacy_HF_EDCF);
 645         /* FIXME kill magic */
 646         b43legacy_write16(dev, 0x688,
 647                           b43legacy_read16(dev, 0x688) | 0x4);
 648 
 649 
 650         /*TODO: We might need some stack support here to get the values. */
 651 }

/* [<][>][^][v][top][bottom][index][help] */